<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Akash Vaghela</title>
    <subtitle>Full-stack engineer building web apps and exploring Rust and the Solana ecosystem.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://akash11.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://akash11.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-12-01T00:00:00+00:00</updated>
    <id>https://akash11.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Zola Portfolio</title>
        <published>2026-05-10T00:00:00+00:00</published>
        <updated>2026-05-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/projects/zola-portfolio/"/>
        <id>https://akash11.com/projects/zola-portfolio/</id>
        
        <content type="html" xml:base="https://akash11.com/projects/zola-portfolio/">&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;A fast, static personal portfolio and blog built with Zola and the Terminus dark theme. Compiles to pure HTML&#x2F;CSS with no JavaScript framework overhead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Terminal-aesthetic dark theme with monospace typography&lt;&#x2F;li&gt;
&lt;li&gt;Blog with pagination and tag taxonomy&lt;&#x2F;li&gt;
&lt;li&gt;Paginated projects section with per-project pages&lt;&#x2F;li&gt;
&lt;li&gt;Deployed on Vercel with zero config&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust CLI Task Manager</title>
        <published>2026-03-22T00:00:00+00:00</published>
        <updated>2026-03-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/projects/rust-cli-tool/"/>
        <id>https://akash11.com/projects/rust-cli-tool/</id>
        
        <content type="html" xml:base="https://akash11.com/projects/rust-cli-tool/">&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;A lightweight terminal task manager that stores tasks in a local JSON file. No account, no internet, no Electron — just a single binary that fits into any terminal workflow.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Add, complete, delete, and filter tasks&lt;&#x2F;li&gt;
&lt;li&gt;Persistent local JSON storage&lt;&#x2F;li&gt;
&lt;li&gt;Coloured output for task states&lt;&#x2F;li&gt;
&lt;li&gt;Single compiled binary, no runtime dependencies&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Signature Malleability from Dirty Bits in Solidity Types</title>
        <published>2025-12-06T00:00:00+00:00</published>
        <updated>2025-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/signature-malleability-from-dirty-bits-in-solidity-types/"/>
        <id>https://akash11.com/blog/signature-malleability-from-dirty-bits-in-solidity-types/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/signature-malleability-from-dirty-bits-in-solidity-types/">&lt;p&gt;Solidity stores all values in 32-byte slots. A &lt;code&gt;uint8&lt;&#x2F;code&gt; only needs 1 byte. The other 31 bytes are unused, and they can hold any data the caller puts there.&lt;&#x2F;p&gt;
&lt;p&gt;For most operations, this does not matter. Solidity masks the unused bits automatically, so your function logic sees clean values. But if your contract hashes &lt;code&gt;msg.data&lt;&#x2F;code&gt; directly (to build a unique transaction ID or verify a signature), those extra bits become part of the hash. Two calls with identical logical parameters but different dirty bits will produce different hashes.&lt;&#x2F;p&gt;
&lt;p&gt;This is the dirty higher-order bits vulnerability. It allows an attacker to replay a transaction your contract believes it has already seen.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;how-solidity-pads-smaller-types&quot;&gt;How Solidity Pads Smaller Types&lt;&#x2F;h2&gt;
&lt;p&gt;Every EVM word is 32 bytes (256 bits). When you pass a &lt;code&gt;uint8&lt;&#x2F;code&gt; to a function, the EVM encodes it in a 32-byte slot. The value goes in the rightmost 8 bits. The remaining 248 bits are the &quot;higher-order&quot; bits, and they can be anything.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a simple example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;padding.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Solidity reads only the lowest 8 bits of the input.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; The upper 248 bits in msg.data are ignored here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These two raw inputs both call &lt;code&gt;transfer(1)&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; Clean input: upper bits are zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x0000000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; Dirty input: upper bits contain arbitrary data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0xff00000000000000000000000000000000000000000000000000000000000001&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Inside the function body, &lt;code&gt;amount&lt;&#x2F;code&gt; equals &lt;code&gt;1&lt;&#x2F;code&gt; in both cases. Solidity masks off the extra bits before your code runs. The problem is that &lt;code&gt;msg.data&lt;&#x2F;code&gt; gives you the raw, unmasked bytes.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;where-the-vulnerability-appears&quot;&gt;Where the Vulnerability Appears&lt;&#x2F;h2&gt;
&lt;p&gt;The issue only matters when your contract hashes &lt;code&gt;msg.data&lt;&#x2F;code&gt;, for example to track whether a transaction has already been executed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;vulnerable.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; VulnerableContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; executed;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; executeOnce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; keccak256(msg.data) includes the dirty upper bits.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Two calls with the same `amount` but different padding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; will produce different hashes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt; txHash &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(!executed[txHash],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Already executed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        executed[txHash]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; ... do something with amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An attacker can call &lt;code&gt;executeOnce(1)&lt;&#x2F;code&gt; twice: once with clean data and once with dirty data. Each call produces a different &lt;code&gt;txHash&lt;&#x2F;code&gt;. The &lt;code&gt;require&lt;&#x2F;code&gt; passes both times. The replay protection is broken.&lt;&#x2F;p&gt;
&lt;p&gt;The attacker does not need any special access. Any caller can craft dirty &lt;code&gt;msg.data&lt;&#x2F;code&gt; by constructing the raw transaction manually.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;which-types-are-affected&quot;&gt;Which Types Are Affected&lt;&#x2F;h2&gt;
&lt;p&gt;Any Solidity type smaller than 32 bytes can carry dirty bits.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Type group&lt;&#x2F;th&gt;&lt;th&gt;Examples&lt;&#x2F;th&gt;&lt;th&gt;Bytes used&lt;&#x2F;th&gt;&lt;th&gt;Bits exposed&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Unsigned integers&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;uint8&lt;&#x2F;code&gt; to &lt;code&gt;uint248&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1-31&lt;&#x2F;td&gt;&lt;td&gt;248 down to 8&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Signed integers&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;int8&lt;&#x2F;code&gt; to &lt;code&gt;int248&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1-31&lt;&#x2F;td&gt;&lt;td&gt;248 down to 8&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Boolean&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;bool&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1 (stored as &lt;code&gt;uint8&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;td&gt;248&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Fixed bytes&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;bytes1&lt;&#x2F;code&gt; to &lt;code&gt;bytes31&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1-31&lt;&#x2F;td&gt;&lt;td&gt;248 down to 8&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Address&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;address&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;96&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Enum&lt;&#x2F;td&gt;&lt;td&gt;depends on value count&lt;&#x2F;td&gt;&lt;td&gt;usually 1&lt;&#x2F;td&gt;&lt;td&gt;usually 248&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Types that fill the full 32 bytes have no unused space:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint256, int256, bytes32  =&amp;gt;  no dirty bits possible&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;&lt;code&gt;address&lt;&#x2F;code&gt; is 20 bytes, leaving 12 bytes (96 bits) unused. Contracts that hash &lt;code&gt;msg.data&lt;&#x2F;code&gt; containing an address parameter are also vulnerable.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;how-to-fix-it&quot;&gt;How to Fix It&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;hash-the-parameters-directly-not-msg-data&quot;&gt;Hash the Parameters Directly, Not &lt;code&gt;msg.data&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The cleanest fix is to never hash &lt;code&gt;msg.data&lt;&#x2F;code&gt;. Hash the decoded, cleaned parameters instead. Solidity cleans the parameters when it decodes them, so &lt;code&gt;abi.encode(amount)&lt;&#x2F;code&gt; will always produce the same bytes for the same logical value, regardless of what the caller put in the upper bits.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;safe.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SafeContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; executed;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; executeOnce&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; abi.encode uses the cleaned, decoded value.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Dirty bits in msg.data have no effect here.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt; paramHash &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(amount));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(!executed[paramHash],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Already executed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        executed[paramHash]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; ... do something with amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;abi.encode&lt;&#x2F;code&gt; pads values to 32 bytes in a canonical way. Two calls with the same logical &lt;code&gt;amount&lt;&#x2F;code&gt; will always produce the same &lt;code&gt;paramHash&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If your function takes multiple parameters, encode them all together:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt; paramHash &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(amount, recipient, nonce));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Do not use &lt;code&gt;abi.encodePacked&lt;&#x2F;code&gt; here. It removes padding, which can create a different kind of collision when types of different sizes are concatenated.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-uint256-when-smaller-types-are-not-necessary&quot;&gt;Use &lt;code&gt;uint256&lt;&#x2F;code&gt; When Smaller Types Are Not Necessary&lt;&#x2F;h3&gt;
&lt;p&gt;Gas savings from &lt;code&gt;uint8&lt;&#x2F;code&gt; over &lt;code&gt;uint256&lt;&#x2F;code&gt; are often minimal. The EVM operates on 32-byte words anyway. If the smaller type is not required by your data model, use the full-width type.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; uint256 leaves no room for dirty bits, so the hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; of msg.data is always canonical for this parameter.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span&gt; txHash &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.data);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; safe with uint256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This only helps if every parameter in the function is a full 32-byte type. One &lt;code&gt;uint8&lt;&#x2F;code&gt; or &lt;code&gt;address&lt;&#x2F;code&gt; in the signature is enough to reintroduce the problem.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;validate-input-to-reject-dirty-calls&quot;&gt;Validate Input to Reject Dirty Calls&lt;&#x2F;h3&gt;
&lt;p&gt;If you must use a smaller type and cannot switch to &lt;code&gt;abi.encode&lt;&#x2F;code&gt;, you can reject calls that contain dirty bits with explicit validation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;validate.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; strictTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Reject any input where the upper bits are not zero.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; This forces callers to submit clean data.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        msg&lt;&#x2F;span&gt;&lt;span&gt;.data.length &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.data[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;:])) ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;(amount),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;        &amp;quot;Dirty input rejected&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; proceed safely&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This approach is more fragile and harder to maintain. The &lt;code&gt;abi.encode&lt;&#x2F;code&gt; fix is simpler and correct by construction.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;recommended-practice&quot;&gt;Recommended Practice&lt;&#x2F;h2&gt;
&lt;p&gt;Always hash cleaned, decoded parameters. Never hash raw &lt;code&gt;msg.data&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Correct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt; id &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(param1, param2));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Vulnerable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span&gt; id &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If your contract tracks executed transactions, generates identifiers from function inputs, or builds any hash from &lt;code&gt;msg.data&lt;&#x2F;code&gt;, audit those call sites. Check the types involved. If any parameter is smaller than 32 bytes, you may have this vulnerability.&lt;&#x2F;p&gt;
&lt;p&gt;The EVM will not protect you here. The caller controls &lt;code&gt;msg.data&lt;&#x2F;code&gt;, and Solidity only cleans inputs for your function body, not before the bytes hit &lt;code&gt;msg.data&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Expense Tracker API</title>
        <published>2025-12-01T00:00:00+00:00</published>
        <updated>2026-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/projects/expense-tracker/"/>
        <id>https://akash11.com/projects/expense-tracker/</id>
        
        <content type="html" xml:base="https://akash11.com/projects/expense-tracker/">&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;A production-ready REST API for tracking personal expenses, assigning categories, and generating monthly summaries. Built API-first so it can connect to any frontend or automation script.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;JWT authentication&lt;&#x2F;li&gt;
&lt;li&gt;Expense CRUD with category tagging&lt;&#x2F;li&gt;
&lt;li&gt;Monthly and category breakdown report endpoints&lt;&#x2F;li&gt;
&lt;li&gt;Dockerised for one-command local dev&lt;&#x2F;li&gt;
&lt;li&gt;OpenAPI docs auto-generated by FastAPI&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;screenshots&quot;&gt;Screenshots&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;s1.png&quot; alt=&quot;image1&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;images&#x2F;s2.png&quot; alt=&quot;image1&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;images&#x2F;s3.png&quot; alt=&quot;image1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;demo&quot;&gt;Demo&lt;&#x2F;h2&gt;
&lt;iframe
    src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;dQw4w9WgXcQ&quot;
    frameborder=&quot;0&quot;
    allowfullscreen
    style=&quot;width:100%;aspect-ratio:16&#x2F;9;display:block;&quot;&gt;
&lt;&#x2F;iframe&gt;
&lt;p&gt;you can download from here if you want&lt;&#x2F;p&gt;
&lt;a href=&quot;&amp;#x2F;files&amp;#x2F;resume.pdf&quot; download class=&quot;download-btn&quot;&gt;
    &lt;svg width=&quot;14&quot; height=&quot;14&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot;
        aria-hidden=&quot;true&quot;&gt;
        &lt;path d=&quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&quot; &#x2F;&gt;
        &lt;polyline points=&quot;7 10 12 15 17 10&quot; &#x2F;&gt;
        &lt;line x1=&quot;12&quot; y1=&quot;15&quot; x2=&quot;12&quot; y2=&quot;3&quot; &#x2F;&gt;
    &lt;&#x2F;svg&gt;
    resume.pdf
    &lt;span class=&quot;download-size&quot;&gt;142 KB&lt;&#x2F;span&gt;
&lt;&#x2F;a&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ERC-2981: How NFT Royalties Work at the Contract Level</title>
        <published>2025-11-22T00:00:00+00:00</published>
        <updated>2025-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/erc-2981-how-nft-royalties-work-at-the-contract-level/"/>
        <id>https://akash11.com/blog/erc-2981-how-nft-royalties-work-at-the-contract-level/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/erc-2981-how-nft-royalties-work-at-the-contract-level/">&lt;p&gt;Before ERC-2981, NFT royalties were a handshake agreement between creators and marketplaces. Each platform did things differently. Most did nothing. A creator could mint a collection, watch it trade for millions in secondary sales, and receive nothing past the initial mint.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-2981 is a standard interface that gives any NFT contract a way to report royalty information: who gets paid, and how much, for a given sale price. Marketplaces that support the standard query this information and route payments correctly.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains how the standard works, how to implement it in Solidity using OpenZeppelin, and what its real limitations are.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-interface&quot;&gt;The Interface&lt;&#x2F;h2&gt;
&lt;p&gt;The entire standard is built around one function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;IERC2981.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC2981&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; royaltyInfo&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; salePrice&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; royaltyAmount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When a supported marketplace processes a sale, it calls &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; with the token ID and the sale price in wei. The contract returns two values: the address that should receive the royalty, and the amount in wei.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s the full interface. The standard does not define how royalties are stored, calculated, or updated. That&#x27;s left to the implementation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;royalties-in-basis-points&quot;&gt;Royalties in Basis Points&lt;&#x2F;h2&gt;
&lt;p&gt;Royalty percentages in ERC-2981 are expressed in basis points. One basis point equals 0.01%, so 10,000 basis points equals 100%.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Percentage&lt;&#x2F;th&gt;&lt;th&gt;Basis Points&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1%&lt;&#x2F;td&gt;&lt;td&gt;100&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2.5%&lt;&#x2F;td&gt;&lt;td&gt;250&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5%&lt;&#x2F;td&gt;&lt;td&gt;500&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;7.5%&lt;&#x2F;td&gt;&lt;td&gt;750&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;10%&lt;&#x2F;td&gt;&lt;td&gt;1000&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The calculation used to convert a sale price to a royalty amount is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;royaltyAmount = (salePrice * feeBasisPoints) &#x2F; 10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For a 2 ETH sale at 5%:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;royaltyAmount = (2_000_000_000_000_000_000 * 500) &#x2F; 10000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;royaltyAmount = 100_000_000_000_000_000 wei = 0.1 ETH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Basis points avoid floating point entirely, which Solidity does not support.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-basic-implementation-with-openzeppelin&quot;&gt;A Basic Implementation with OpenZeppelin&lt;&#x2F;h2&gt;
&lt;p&gt;OpenZeppelin provides an &lt;code&gt;ERC2981&lt;&#x2F;code&gt; base contract that handles the storage and calculation logic. You inherit it alongside &lt;code&gt;ERC721&lt;&#x2F;code&gt; and override &lt;code&gt;supportsInterface()&lt;&#x2F;code&gt; to declare both:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;MyNFT.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.20&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;ERC721.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;common&#x2F;ERC2981.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; MyNFT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ERC2981&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;MyNFT&amp;quot;, &amp;quot;MNFT&amp;quot;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; 5% royalty to the deployer for all tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _setDefaultRoyalty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 500&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Required when inheriting multiple contracts that implement supportsInterface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        virtual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC2981&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(interfaceId);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;_setDefaultRoyalty()&lt;&#x2F;code&gt; call sets a royalty that applies to every token in the collection unless overridden.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;default-royalties-vs-per-token-royalties&quot;&gt;Default Royalties vs Per-Token Royalties&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-2981 supports two royalty models. You can use either or both in the same contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Default royalty&lt;&#x2F;strong&gt; applies to every token that does not have its own royalty set:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;_setDefaultRoyalty&lt;&#x2F;span&gt;&lt;span&gt;(creatorAddress,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 750&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; 7.5% for all tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Per-token royalty&lt;&#x2F;strong&gt; overrides the default for a specific token:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;_setTokenRoyalty&lt;&#x2F;span&gt;&lt;span&gt;(tokenId, specificCreator,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; 10% for this token only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Per-token royalties are useful for collaborative collections where different artists contribute individual pieces and each should receive royalties from their own work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-complete-example-mintable-collection-with-updatable-royalties&quot;&gt;A Complete Example: Mintable Collection with Updatable Royalties&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a more realistic contract. Each token sets its royalty to the minting address at mint time. The token owner can update the royalty later.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;ArtCollection.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.20&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC721&#x2F;ERC721.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;common&#x2F;ERC2981.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ArtCollection&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ERC2981&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _nextTokenId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC721&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;Art Collection&amp;quot;, &amp;quot;ART&amp;quot;) {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= ++&lt;&#x2F;span&gt;&lt;span&gt;_nextTokenId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _safeMint&lt;&#x2F;span&gt;&lt;span&gt;(to, tokenId);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; 2.5% royalty going to the minting address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _setTokenRoyalty&lt;&#x2F;span&gt;&lt;span&gt;(tokenId, to,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 250&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; tokenId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; updateRoyalty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint96&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; feeNumerator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(tokenId) ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Not token owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _setTokenRoyalty&lt;&#x2F;span&gt;&lt;span&gt;(tokenId, receiver, feeNumerator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        view&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ERC721&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC2981&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt; super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(interfaceId);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
&lt;p&gt;Allowing token owners to update royalties is a design choice with real tradeoffs. It gives flexibility but also lets someone change where royalties go after a token is sold. Consider whether that fits your use case before including &lt;code&gt;updateRoyalty()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;how-marketplaces-check-for-support&quot;&gt;How Marketplaces Check for Support&lt;&#x2F;h2&gt;
&lt;p&gt;Before calling &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt;, a marketplace should verify the contract declares ERC-2981 support through ERC-165:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private constant&lt;&#x2F;span&gt;&lt;span&gt; _INTERFACE_ID_ERC2981 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0x2a55205a&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; supportsRoyalties&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; nftContract&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; IERC165&lt;&#x2F;span&gt;&lt;span&gt;(nftContract).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(_INTERFACE_ID_ERC2981)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; supported&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; supported;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The interface ID &lt;code&gt;0x2a55205a&lt;&#x2F;code&gt; is derived from the &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; function selector. It is fixed by the standard.&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; is a &lt;code&gt;view&lt;&#x2F;code&gt; function, calling it costs no gas. Marketplaces can query royalty data off-chain when building a transaction, then include the royalty transfer in the sale transaction itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-erc-2981-cannot-do&quot;&gt;What ERC-2981 Cannot Do&lt;&#x2F;h2&gt;
&lt;p&gt;The standard has three limitations worth understanding before you rely on it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Royalties are not enforced.&lt;&#x2F;strong&gt; A marketplace can call &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; and then ignore the result. The standard provides information, not enforcement. There is no mechanism in the standard itself to block a transfer on a non-compliant platform.&lt;&#x2F;p&gt;
&lt;p&gt;OpenSea attempted to address this in 2022 with the Operator Filter Registry, which let creators block transfers through contracts that did not honor royalties. The approach had mixed results and generated significant debate about creator rights versus open market access. It remains an unsolved problem at the protocol level.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Only one recipient per token.&lt;&#x2F;strong&gt; &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; returns a single &lt;code&gt;address&lt;&#x2F;code&gt;. If you want royalties split among multiple collaborators, you need a separate payment splitter contract that acts as the recipient and redistributes funds internally:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;PaymentSplitter.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; RoyaltySplitter&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; payees;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; shares;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _payees&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _shares&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; store payees and their share ratios&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; distribute incoming ETH proportionally&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You would deploy this splitter, then set its address as the royalty receiver in your NFT contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Marketplace adoption is not guaranteed.&lt;&#x2F;strong&gt; Major platforms like OpenSea, Rarible, and LooksRare support ERC-2981. Smaller exchanges, aggregators, and peer-to-peer tools may not. If someone trades your NFT through a non-supporting venue, the royalty is not paid and nothing in the standard can stop that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-to-use-erc-2981&quot;&gt;When to Use ERC-2981&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-2981 is the right choice when:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You are building a new NFT collection and want royalty support on major marketplaces&lt;&#x2F;li&gt;
&lt;li&gt;Different tokens in your collection should have different royalty rates or recipients&lt;&#x2F;li&gt;
&lt;li&gt;You want a standard that existing tooling already understands&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is not a complete solution when on-chain royalty enforcement is a hard requirement. For that, you need transfer restrictions at the token level, which come with their own tradeoffs around composability and user experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-2981 solves a specific, narrow problem: it gives NFT contracts a standard way to report royalty information. Any marketplace that queries &lt;code&gt;royaltyInfo()&lt;&#x2F;code&gt; and acts on the result will pay royalties correctly. The standard works well for that purpose.&lt;&#x2F;p&gt;
&lt;p&gt;What it does not solve is enforcement. A standard can only define a shared language. Whether platforms respect that language is a social and economic question, not a technical one.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ERC-4626: The Tokenized Vault Standard Explained</title>
        <published>2025-11-22T00:00:00+00:00</published>
        <updated>2025-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/erc-4626-tokenized-vault-standard/"/>
        <id>https://akash11.com/blog/erc-4626-tokenized-vault-standard/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/erc-4626-tokenized-vault-standard/">&lt;p&gt;ERC-4626 is a Solidity interface standard for yield-bearing vaults. It defines a single, consistent way for protocols to accept deposits, issue shares, and return assets on withdrawal. This post explains how the standard works, why the math behaves the way it does, and what to watch out for when implementing or integrating with it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem-it-solves&quot;&gt;The Problem It Solves&lt;&#x2F;h2&gt;
&lt;p&gt;Before ERC-4626, every yield protocol built its own vault interface. Yearn issued &lt;code&gt;yTokens&lt;&#x2F;code&gt;. Compound issued &lt;code&gt;cTokens&lt;&#x2F;code&gt;. Aave issued &lt;code&gt;aTokens&lt;&#x2F;code&gt;. Each worked differently at the function level.&lt;&#x2F;p&gt;
&lt;p&gt;This meant every integration required custom code. An aggregator that wanted to support five yield protocols had to write five different adapters. A bug in one adapter did not apply to the others. Auditing was harder. Development was slower.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-4626 gives every vault the same function signatures and the same mathematical guarantees. Deposit tokens, receive shares. Redeem shares, receive tokens. An aggregator written against ERC-4626 works with any compliant vault without modification.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-shares-and-assets-relate&quot;&gt;How Shares and Assets Relate&lt;&#x2F;h2&gt;
&lt;p&gt;A vault holds an underlying &lt;code&gt;asset&lt;&#x2F;code&gt; (for example, USDC). When you deposit, you receive &lt;code&gt;shares&lt;&#x2F;code&gt; in return. Shares represent your proportional ownership of everything inside the vault.&lt;&#x2F;p&gt;
&lt;p&gt;The relationship between shares and assets is defined by this ratio:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;exchange rate = totalAssets() &#x2F; totalSupply()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At launch, a vault typically starts at 1:1. As the vault earns yield and &lt;code&gt;totalAssets()&lt;&#x2F;code&gt; grows, each share becomes redeemable for more of the underlying asset.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a concrete example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;State: 10,000 USDC in the vault, 8,000 shares outstanding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Exchange rate: 10,000 &#x2F; 8,000 = 1.25 USDC per share&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;You deposit 1,000 USDC:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Shares minted = 1,000 &#x2F; 1.25 = 800 shares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Later, the vault earns yield: now 11,000 USDC, 8,800 shares outstanding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;You redeem your 800 shares:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Assets returned = 800 * (11,000 &#x2F; 8,800) = 1,000 USDC * 1.04... ≈ 1,045 USDC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Your shares became worth more. You did not need to claim anything. The exchange rate carried the yield.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-core-interface&quot;&gt;The Core Interface&lt;&#x2F;h2&gt;
&lt;p&gt;Every ERC-4626 vault implements these functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Returns the address of the underlying token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; asset&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Returns total underlying tokens managed by the vault&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalAssets&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Deposits `assets` tokens, mints shares to `receiver`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Mints exactly `shares` shares, pulls required assets from caller&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Burns shares from `owner`, sends exactly `assets` tokens to `receiver`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Burns exactly `shares` from `owner`, sends resulting tokens to `receiver`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; redeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Preview functions (view, no state changes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; previewDeposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; previewMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; previewWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; previewRedeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Limits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; maxDeposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; maxMint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; maxWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; maxRedeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;deposit-vs-mint-withdraw-vs-redeem&quot;&gt;Deposit vs Mint, Withdraw vs Redeem&lt;&#x2F;h3&gt;
&lt;p&gt;The standard provides two entry paths and two exit paths. The difference is which side you fix.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;You fix&lt;&#x2F;th&gt;&lt;th&gt;The vault determines&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;deposit&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;How many assets to put in&lt;&#x2F;td&gt;&lt;td&gt;How many shares you receive&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mint&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;How many shares you want&lt;&#x2F;td&gt;&lt;td&gt;How many assets to pull&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;withdraw&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;How many assets to get back&lt;&#x2F;td&gt;&lt;td&gt;How many shares to burn&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;redeem&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;How many shares to burn&lt;&#x2F;td&gt;&lt;td&gt;How many assets to return&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Use &lt;code&gt;deposit&lt;&#x2F;code&gt; and &lt;code&gt;redeem&lt;&#x2F;code&gt; in most cases. Use &lt;code&gt;mint&lt;&#x2F;code&gt; and &lt;code&gt;withdraw&lt;&#x2F;code&gt; when the contract on the other side needs exact amounts, such as when fulfilling a specific share-denominated obligation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-minimal-implementation&quot;&gt;A Minimal Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;The simplest compliant vault just holds tokens in place, with no yield strategy at all:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;BasicVault.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.20&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ERC4626&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC20&#x2F;extensions&#x2F;ERC4626.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;ERC20&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC20&#x2F;ERC20.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;IERC20&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC20&#x2F;IERC20.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; BasicVault&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ERC4626&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        IERC20&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _asset&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _name&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _symbol&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC4626&lt;&#x2F;span&gt;&lt;span&gt;(_asset) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ERC20&lt;&#x2F;span&gt;&lt;span&gt;(_name, _symbol) {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalAssets&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view override returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; IERC20&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;asset&lt;&#x2F;span&gt;&lt;span&gt;()).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Real vaults deploy yield strategies inside &lt;code&gt;totalAssets()&lt;&#x2F;code&gt; or through a separate &lt;code&gt;harvest()&lt;&#x2F;code&gt; function that compounds returns and updates the vault&#x27;s balance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-inflation-attack&quot;&gt;The Inflation Attack&lt;&#x2F;h2&gt;
&lt;p&gt;Early vault designs had a known exploit. Here is how it works:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;An attacker deposits 1 wei as the first depositor. They receive 1 share.&lt;&#x2F;li&gt;
&lt;li&gt;The attacker transfers 1,000,000 tokens directly to the vault contract (not through &lt;code&gt;deposit&lt;&#x2F;code&gt;). This does not mint shares.&lt;&#x2F;li&gt;
&lt;li&gt;The exchange rate is now 1,000,001 assets per share.&lt;&#x2F;li&gt;
&lt;li&gt;A victim deposits 999,999 tokens. Integer division gives them 0 shares.&lt;&#x2F;li&gt;
&lt;li&gt;The victim receives nothing. The attacker redeems their 1 share and takes everything.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Two approaches defend against this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;virtual-offset&quot;&gt;Virtual Offset&lt;&#x2F;h3&gt;
&lt;p&gt;Add a virtual balance and virtual supply to the exchange rate calculation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;VirtualOffsetVault.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; _convertToShares&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; Math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;Rounding&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; rounding&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    internal view override returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; assets.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;mulDiv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        totalSupply&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; _decimalsOffset&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; virtual supply offset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        totalAssets&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;                         &#x2F;&#x2F; virtual asset offset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        rounding&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;OpenZeppelin&#x27;s &lt;code&gt;ERC4626&lt;&#x2F;code&gt; implementation uses a &lt;code&gt;_decimalsOffset()&lt;&#x2F;code&gt; hook for exactly this purpose. Setting it to a non-zero value (commonly &lt;code&gt;0&lt;&#x2F;code&gt; for most tokens, higher for tokens with few decimals) adds the offset automatically.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dead-shares&quot;&gt;Dead Shares&lt;&#x2F;h3&gt;
&lt;p&gt;Mint a small number of shares to &lt;code&gt;address(0)&lt;&#x2F;code&gt; in the constructor, permanently locking them:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;DeadSharesVault.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;IERC20&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _asset&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC4626&lt;&#x2F;span&gt;&lt;span&gt;(_asset) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;ERC20&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;Vault&amp;quot;, &amp;quot;vTKN&amp;quot;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Lock initial liquidity so the exchange rate cannot be manipulated cheaply&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0xdead&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This raises the cost of the attack significantly. The attacker would need to donate enough to overwhelm the dead shares.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;If you deploy a vault without inflation protection and someone front-runs the first deposit, the vault can be permanently broken for honest users. Add protection before deployment, not after.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;fee-structures&quot;&gt;Fee Structures&lt;&#x2F;h2&gt;
&lt;p&gt;Vaults typically charge fees through share dilution rather than direct asset transfers. A performance fee works like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;FeeVault.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; harvest&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; currentAssets &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalAssets&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; profit &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; currentAssets &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; lastRecordedAssets;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (profit &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; feeInAssets &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (profit &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; performanceFee)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10_000&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; basis points&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; feeShares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; convertToShares&lt;&#x2F;span&gt;&lt;span&gt;(feeInAssets);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Minting shares to the protocol dilutes all other holders proportionally&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(feeRecipient, feeShares);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        lastRecordedAssets &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalAssets&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Minting shares to a recipient reduces the share price for everyone else by a small, proportional amount. No asset transfers happen. The fee is implicit in the dilution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;integrating-with-erc-4626-vaults&quot;&gt;Integrating with ERC-4626 Vaults&lt;&#x2F;h2&gt;
&lt;p&gt;Because every ERC-4626 vault exposes the same interface, aggregators and routers can interact with any compliant vault using the same code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;DeFiAggregator.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC4626&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; asset&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; redeem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; previewDeposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; assets&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; shares&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; VaultRouter&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; zapIntoVault&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;IERC4626&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; vault&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        IERC20 underlying &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; IERC20&lt;&#x2F;span&gt;&lt;span&gt;(vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;asset&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        underlying.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;), amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;        underlying.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(vault), amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;deposit&lt;&#x2F;span&gt;&lt;span&gt;(amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This router works for any vault, whether it is a Yearn strategy, a Beefy compounder, or a custom protocol, as long as the vault implements ERC-4626.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;real-world-considerations&quot;&gt;Real-World Considerations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;slippage-protection&quot;&gt;Slippage Protection&lt;&#x2F;h3&gt;
&lt;p&gt;Always check preview functions before transacting and enforce a minimum output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; expectedShares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;previewDeposit&lt;&#x2F;span&gt;&lt;span&gt;(amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; minShares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (expectedShares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 99&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; 1% slippage tolerance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; actualShares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;deposit&lt;&#x2F;span&gt;&lt;span&gt;(amount, receiver);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(actualShares &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; minShares,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Slippage exceeded&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some vaults charge entry or exit fees that the preview functions may not fully account for, depending on implementation. Read the vault documentation before assuming previews are exact.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deposit-and-withdrawal-limits&quot;&gt;Deposit and Withdrawal Limits&lt;&#x2F;h3&gt;
&lt;p&gt;Vaults can cap total deposits or impose per-user limits. Always check before transacting:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; depositLimit &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;maxDeposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(depositAmount &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; depositLimit,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Exceeds vault capacity&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;withdrawal-delays&quot;&gt;Withdrawal Delays&lt;&#x2F;h3&gt;
&lt;p&gt;Some yield strategies lock assets in external protocols. The vault may not be able to return funds immediately. &lt;code&gt;maxWithdraw()&lt;&#x2F;code&gt; and &lt;code&gt;maxRedeem()&lt;&#x2F;code&gt; tell you how much is available right now:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; availableNow &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;maxWithdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (desiredAmount &amp;gt; availableNow) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Handle partial withdrawal or enter a withdrawal queue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;rounding&quot;&gt;Rounding&lt;&#x2F;h3&gt;
&lt;p&gt;Integer division always truncates. The standard specifies how to round: round in favor of the vault on deposits, round in favor of the user on withdrawals. This prevents users from extracting value through repeated small operations.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Deposit: round shares DOWN (vault-favorable)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;shares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; assets.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;mulDiv&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;totalSupply&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalAssets&lt;&#x2F;span&gt;&lt;span&gt;(), Math.Rounding.Floor);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Withdraw: round shares UP (user-favorable, meaning fewer shares burned)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Redeem: round assets DOWN (user-favorable, meaning fewer assets expected to be exact)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;OpenZeppelin&#x27;s implementation handles this correctly. If you are writing a custom vault, verify your rounding direction matches the spec.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-risks&quot;&gt;Security Risks&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Reentrancy.&lt;&#x2F;strong&gt; Deposit and withdrawal functions transfer tokens, which can trigger callbacks in ERC-777 or similar token contracts. Use the checks-effects-interactions pattern or a reentrancy guard on all external-facing vault functions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Oracle manipulation.&lt;&#x2F;strong&gt; If &lt;code&gt;totalAssets()&lt;&#x2F;code&gt; reads a price from an AMM or external oracle, a flash loan can manipulate the exchange rate within a single transaction. Use time-weighted average prices or other manipulation-resistant methods if your vault&#x27;s asset accounting depends on price feeds.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Direct token transfers.&lt;&#x2F;strong&gt; Tokens sent to the vault address without calling &lt;code&gt;deposit()&lt;&#x2F;code&gt; increase &lt;code&gt;totalAssets()&lt;&#x2F;code&gt; but do not mint shares. This is a donation that benefits all existing shareholders. It can also be used as part of an inflation attack if the vault is not protected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing-fundamentals&quot;&gt;Testing Fundamentals&lt;&#x2F;h2&gt;
&lt;p&gt;Two properties must hold for any correct vault implementation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Round-trip integrity:&lt;&#x2F;strong&gt; depositing and immediately withdrawing should return approximately the same amount, minus only legitimate fees and rounding:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;VaultTest.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; testRoundTrip&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; depositAmount &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1000e18&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; shares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;deposit&lt;&#x2F;span&gt;&lt;span&gt;(depositAmount, user);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; assetsBack &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;redeem&lt;&#x2F;span&gt;&lt;span&gt;(shares, user, user);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Allow for rounding up to 2 wei&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    assertApproxEqAbs&lt;&#x2F;span&gt;&lt;span&gt;(assetsBack, depositAmount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Inflation resistance:&lt;&#x2F;strong&gt; a direct token transfer to the vault should not allow an attacker to extract a later depositor&#x27;s funds:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;VaultTest.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; testInflationAttack&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Attacker plants a small deposit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;    vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, attacker);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Attacker donates directly to the vault contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    token.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(vault),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1e18&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Victim deposits a large amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; shares &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; vault.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1000e18&lt;&#x2F;span&gt;&lt;span&gt;, victim);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Victim must receive meaningful shares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    assertGt&lt;&#x2F;span&gt;&lt;span&gt;(shares,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If your vault fails the second test, you need inflation protection before deployment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-erc-4626-fits-and-when-it-does-not&quot;&gt;When ERC-4626 Fits and When It Does Not&lt;&#x2F;h2&gt;
&lt;p&gt;The standard works well for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Yield aggregators that pool user deposits into a single strategy&lt;&#x2F;li&gt;
&lt;li&gt;Single-asset staking with auto-compounding returns&lt;&#x2F;li&gt;
&lt;li&gt;Lending protocols where depositors earn interest over time&lt;&#x2F;li&gt;
&lt;li&gt;Treasury management systems that need a standardized vault interface&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is a poor fit for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Multi-asset vaults. The standard assumes one underlying &lt;code&gt;asset&lt;&#x2F;code&gt;. Vaults that hold baskets of tokens require a different design.&lt;&#x2F;li&gt;
&lt;li&gt;NFT-based strategies. Shares are fungible ERC-20 tokens. You cannot represent fractional or unique positions within the standard.&lt;&#x2F;li&gt;
&lt;li&gt;Vaults with complex, conditional withdrawal rules. &lt;code&gt;maxWithdraw()&lt;&#x2F;code&gt; is a simple integer. If withdrawal eligibility depends on time locks, governance votes, or other state, the standard cannot express that fully.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-4626 standardizes the deposit-share-redeem cycle so that any integrator can work with any compliant vault using the same code. The exchange rate rises as yield accumulates. Preview functions let callers simulate outcomes before transacting. The standard has known risks (inflation attacks, rounding, reentrancy) that have established mitigations.&lt;&#x2F;p&gt;
&lt;p&gt;If you are building a new yield vault, start from OpenZeppelin&#x27;s &lt;code&gt;ERC4626&lt;&#x2F;code&gt; base contract. It handles the exchange rate math, rounding direction, and inflation protection correctly. Add your yield strategy on top.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ERC-777: The Token Standard That Tried to Fix ERC-20</title>
        <published>2025-11-22T00:00:00+00:00</published>
        <updated>2025-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/erc-777-the-token-standard-that-tried-to-fix-erc-20/"/>
        <id>https://akash11.com/blog/erc-777-the-token-standard-that-tried-to-fix-erc-20/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/erc-777-the-token-standard-that-tried-to-fix-erc-20/">&lt;p&gt;ERC-777 was proposed in 2017 to fix a specific, well-known problem: ERC-20 tokens had no way to notify a contract when tokens arrived. This caused tokens to get stuck in contracts silently, and it forced developers to use the awkward &lt;code&gt;approve&lt;&#x2F;code&gt; + &lt;code&gt;transferFrom&lt;&#x2F;code&gt; two-step flow. ERC-777 introduced hooks, operators, and a richer send interface to address these problems.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers how ERC-777 works, what it adds over ERC-20, where it struggles, and why most projects still avoid it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem-erc-777-solves&quot;&gt;The Problem ERC-777 Solves&lt;&#x2F;h2&gt;
&lt;p&gt;With ERC-20, if you send tokens directly to a contract using &lt;code&gt;transfer&lt;&#x2F;code&gt;, the contract has no idea the tokens arrived. There is no callback, no notification, no hook. The tokens sit in the contract with no way to trigger any logic.&lt;&#x2F;p&gt;
&lt;p&gt;The workaround is the &lt;code&gt;approve&lt;&#x2F;code&gt; + &lt;code&gt;transferFrom&lt;&#x2F;code&gt; pattern. You first call &lt;code&gt;approve&lt;&#x2F;code&gt; to allow the contract to pull tokens, then the contract calls &lt;code&gt;transferFrom&lt;&#x2F;code&gt; to actually take them. Two transactions. Two signatures. Higher gas costs.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-777 replaces both of these patterns with a hook system. When tokens arrive at a contract, the standard automatically calls a function on that contract to notify it. This makes token receipt an event the contract can respond to, not something it has to poll or pull.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hooks-the-core-innovation&quot;&gt;Hooks: The Core Innovation&lt;&#x2F;h2&gt;
&lt;p&gt;The key addition in ERC-777 is two hooks: &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; and &lt;code&gt;tokensReceived&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;tokensToSend&lt;&#x2F;code&gt; is optional. It fires before tokens leave the sender&#x27;s address. A sender contract can implement this to intercept or reject outgoing transfers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;tokensReceived&lt;&#x2F;code&gt; is mandatory for contract recipients. If a contract receives ERC-777 tokens but does not implement &lt;code&gt;tokensReceived&lt;&#x2F;code&gt;, the transfer reverts. This prevents tokens from being sent to contracts that cannot handle them.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; tokensReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; userData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operatorData&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;userData&lt;&#x2F;code&gt; and &lt;code&gt;operatorData&lt;&#x2F;code&gt; parameters are also new. They let the sender attach arbitrary bytes to a transfer, similar to a memo on a bank transfer. A receiving contract can parse these bytes to decide what to do with the incoming tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;operators&quot;&gt;Operators&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-777 introduces the concept of operators: addresses that are authorized to send tokens on behalf of another address. This is different from ERC-20&#x27;s &lt;code&gt;approve&lt;&#x2F;code&gt; mechanism.&lt;&#x2F;p&gt;
&lt;p&gt;With ERC-20 &lt;code&gt;approve&lt;&#x2F;code&gt;, you authorize a specific spender to spend up to a specific amount. With ERC-777 operators, you authorize an address to move any amount of your tokens until you revoke that authorization.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Authorize an operator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; authorizeOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Revoke an operator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; revokeOperator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Check authorization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; isOperatorFor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenHolder&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is also a concept of default operators. These are addresses the token creator designates as operators for all token holders at deployment time. They can be used for things like automatic fee collection or protocol-level transfers. Token holders can revoke default operators individually, but they are active by default unless revoked.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-send-interface&quot;&gt;The Send Interface&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-777 replaces &lt;code&gt;transfer&lt;&#x2F;code&gt; with &lt;code&gt;send&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;data&lt;&#x2F;code&gt; parameter is the memo. Any contract or wallet can pass arbitrary bytes here, and the recipient contract receives them in &lt;code&gt;tokensReceived&lt;&#x2F;code&gt;. This enables use cases like routing logic inside a vault, attaching order IDs to payments, or passing configuration flags alongside a transfer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-a-transfer-actually-flows&quot;&gt;How a Transfer Actually Flows&lt;&#x2F;h2&gt;
&lt;p&gt;When you call &lt;code&gt;send&lt;&#x2F;code&gt;, the execution follows this sequence:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Check the sender has enough balance.&lt;&#x2F;li&gt;
&lt;li&gt;Look up if the sender is a contract. If it is, call &lt;code&gt;tokensToSend&lt;&#x2F;code&gt; on it if the sender has registered an implementation.&lt;&#x2F;li&gt;
&lt;li&gt;Deduct the balance from the sender and add it to the recipient.&lt;&#x2F;li&gt;
&lt;li&gt;Look up if the recipient is a contract. If it is, call &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; on it. This call is required. If the recipient is a contract and does not implement &lt;code&gt;tokensReceived&lt;&#x2F;code&gt;, the whole transaction reverts.&lt;&#x2F;li&gt;
&lt;li&gt;Transfer completes.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The lookup in steps 2 and 4 is done using the ERC-1820 registry, described below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;erc-1820-the-interface-registry&quot;&gt;ERC-1820: The Interface Registry&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-777 depends on ERC-1820, a global registry contract deployed at the same address on every EVM-compatible chain:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ERC-1820 answers the question: &quot;does this address implement interface X?&quot; Every ERC-777 token registers itself with ERC-1820. Every contract that wants to receive ERC-777 tokens registers its &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; implementation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; constant&lt;&#x2F;span&gt;&lt;span&gt; TOKENS_RECIPIENT_INTERFACE_HASH &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;    keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;ERC777TokensRecipient&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; implementer &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; erc1820Registry.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;getInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;    account,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;    TOKENS_RECIPIENT_INTERFACE_HASH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If &lt;code&gt;implementer&lt;&#x2F;code&gt; is the zero address, the recipient has not registered a &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; hook. For a contract recipient, this causes the transfer to revert.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;backward-compatibility-with-erc-20&quot;&gt;Backward Compatibility with ERC-20&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-777 tokens implement all ERC-20 functions. Old interfaces, wallets, and contracts that only know about ERC-20 will still work with an ERC-777 token.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; These still work on an ERC-777 token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The catch: when you use ERC-20 functions on an ERC-777 token, the hooks do not fire. The &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; callback does not execute. This matters if a contract depends on the hook to update state when tokens arrive. If someone sends tokens via the ERC-20 &lt;code&gt;transfer&lt;&#x2F;code&gt; path, the hook is skipped and the contract state may become inconsistent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-working-receiver-contract&quot;&gt;A Working Receiver Contract&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a minimal vault contract that correctly receives ERC-777 tokens:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;TokenVault.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC777&#x2F;IERC777.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC777&#x2F;IERC777Recipient.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;utils&#x2F;introspection&#x2F;IERC1820Registry.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TokenVault&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC777Recipient&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    IERC777 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span&gt; token;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    IERC1820Registry &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;private constant&lt;&#x2F;span&gt;&lt;span&gt; _ERC1820_REGISTRY &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        IERC1820Registry&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bytes32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private constant&lt;&#x2F;span&gt;&lt;span&gt; _TOKENS_RECIPIENT_INTERFACE_HASH &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;        keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;ERC777TokensRecipient&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenAddress&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;        token &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; IERC777&lt;&#x2F;span&gt;&lt;span&gt;(tokenAddress);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Register this contract as a tokensReceived implementer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;        _ERC1820_REGISTRY.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;setInterfaceImplementer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;            _TOKENS_RECIPIENT_INTERFACE_HASH,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; tokensReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; userData&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operatorData&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external override&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(token),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Unknown token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Tokens are already credited to this contract at this point.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; userData can be parsed here to trigger specific vault logic.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that the constructor registers the contract with ERC-1820. Without this registration, any ERC-777 transfer to this address would revert.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-the-reentrancy-problem&quot;&gt;Security: The Reentrancy Problem&lt;&#x2F;h2&gt;
&lt;p&gt;The hook mechanism introduces a serious reentrancy risk. When &lt;code&gt;send&lt;&#x2F;code&gt; is called, it executes the recipient&#x27;s &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; function before the transfer fully settles in some implementations. A malicious or buggy recipient can re-enter the calling contract during this callback.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Vulnerable pattern&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;    token.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Calls tokensReceived on msg.sender&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;    userBalance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; State updated after external call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On line 3, &lt;code&gt;send&lt;&#x2F;code&gt; triggers &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; on &lt;code&gt;msg.sender&lt;&#x2F;code&gt;. If &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is a malicious contract, it can call &lt;code&gt;withdraw&lt;&#x2F;code&gt; again inside &lt;code&gt;tokensReceived&lt;&#x2F;code&gt; before line 4 executes. The balance check passes each time because &lt;code&gt;userBalance&lt;&#x2F;code&gt; has not been decremented yet.&lt;&#x2F;p&gt;
&lt;p&gt;This is not hypothetical. In 2020, several DeFi protocols that used ERC-777 tokens suffered reentrancy attacks exploiting exactly this pattern. The hooks make the attack surface larger than with plain ERC-20.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;If you work with ERC-777 tokens, always follow the checks-effects-interactions pattern. Update state before making any external call, including &lt;code&gt;send&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The hook mechanism also means gas costs are higher and harder to predict. You are executing unknown code in the recipient contract. The gas usage for a transfer depends on what the recipient&#x27;s hook does.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-erc-777-never-replaced-erc-20&quot;&gt;Why ERC-777 Never Replaced ERC-20&lt;&#x2F;h2&gt;
&lt;p&gt;The problems ERC-777 solved were real. The hooks are genuinely useful. But the standard came with enough new risks that most developers chose not to adopt it.&lt;&#x2F;p&gt;
&lt;p&gt;The reentrancy attacks in 2020 made the tradeoffs concrete. It is not that ERC-777 is insecure by design, but that it makes writing secure contracts harder. Developers need to be aware of the hook execution order, register with ERC-1820, and handle the ERC-20 compatibility gap carefully.&lt;&#x2F;p&gt;
&lt;p&gt;Major protocols explicitly rejected ERC-777 over these concerns. Uniswap only supports ERC-20. When a protocol as widely used as Uniswap does not support a standard, that standard will not become the default.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-20 also has momentum. Tooling, auditing patterns, wallet support, and developer intuition are all built around ERC-20. Switching to ERC-777 means relearning assumptions that were already settled.&lt;&#x2F;p&gt;
&lt;p&gt;Newer standards like ERC-4626 for vault tokens and ERC-1155 for multi-token contracts solve specific problems without inheriting ERC-777&#x27;s complexity. Projects that need richer token behavior tend to go to one of those instead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-erc-777-is-worth-considering&quot;&gt;When ERC-777 Is Worth Considering&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-777 is not useless. It fits specific situations where the hook mechanism provides real value and the team is prepared to handle the security implications.&lt;&#x2F;p&gt;
&lt;p&gt;Protocol-level tokens where operators are needed for automated logic are a reasonable fit. Tokens used inside closed systems where every recipient is a known, audited contract are another case where the risks are more contained.&lt;&#x2F;p&gt;
&lt;p&gt;If you are building a simple fungible token for general use, stick with ERC-20. If you need vault or yield-bearing token behavior, look at ERC-4626. ERC-777 occupies a narrow space where its specific features are the right tool for the job.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-777 introduced three meaningful improvements over ERC-20: hooks for contract notification, operators for delegated token management, and a richer &lt;code&gt;send&lt;&#x2F;code&gt; interface with attached data. It maintained backward compatibility with ERC-20 to avoid a hard migration.&lt;&#x2F;p&gt;
&lt;p&gt;In practice, the reentrancy risks from hooks, the dependency on ERC-1820, the gas unpredictability, and the ERC-20 compatibility gap made adoption slow. Most of the ecosystem stayed on ERC-20, and the specific problems ERC-777 solved were addressed through better patterns and auditing rather than a new standard.&lt;&#x2F;p&gt;
&lt;p&gt;The concepts ERC-777 introduced are still worth understanding. Hooks, operator patterns, and attached data are ideas that appear in other standards and protocols. Knowing how ERC-777 implemented them, and where the implementation went wrong, is useful context for working with any token system.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ERC-1155: The Multi-Token Standard for Ethereum</title>
        <published>2025-11-21T00:00:00+00:00</published>
        <updated>2025-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/erc-1155-the-multi-token-standard-for-ethereum/"/>
        <id>https://akash11.com/blog/erc-1155-the-multi-token-standard-for-ethereum/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/erc-1155-the-multi-token-standard-for-ethereum/">&lt;p&gt;Before ERC-1155, building a game with both a currency token and unique item NFTs meant deploying two separate contracts. One ERC-20 for the currency. One ERC-721 for the items. Every additional token type meant another deployment, more gas, and more contracts to maintain.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-1155 solves this. One contract manages unlimited token types, handles fungible and non-fungible tokens, and supports batch operations that reduce transaction costs substantially.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains how ERC-1155 works, walks through real implementation patterns, and compares it to ERC-20 and ERC-721 so you know when to reach for each.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-core-idea&quot;&gt;The Core Idea&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-1155 introduces a two-dimensional balance mapping. Where ERC-20 maps &lt;code&gt;address =&amp;gt; uint256&lt;&#x2F;code&gt;, ERC-1155 maps &lt;code&gt;address =&amp;gt; tokenId =&amp;gt; uint256&lt;&#x2F;code&gt;. That extra dimension is everything.&lt;&#x2F;p&gt;
&lt;p&gt;Each token type gets an ID. The same ID can represent a fungible token (minted in quantity N) or an NFT (minted in quantity 1). The contract does not distinguish between them at the protocol level. You decide what each ID means.&lt;&#x2F;p&gt;
&lt;p&gt;Think of it as a warehouse with numbered bins:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Warehouse (ERC-1155 Contract)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── Bin #0: Gold Coins       (fungible,      quantity: 1,000,000)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── Bin #1: Legendary Sword  (NFT,           quantity: 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── Bin #2: Common Shield    (semi-fungible, quantity: 500)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── Bin #3: Rare Potion      (semi-fungible, quantity: 50)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One warehouse. One deployment. Any mix of token types.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-implementation&quot;&gt;Basic Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a minimal ERC-1155 contract using OpenZeppelin:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;GameItems.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC1155&#x2F;ERC1155.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; GameItems&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ERC1155&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public constant&lt;&#x2F;span&gt;&lt;span&gt; GOLD   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public constant&lt;&#x2F;span&gt;&lt;span&gt; SWORD  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public constant&lt;&#x2F;span&gt;&lt;span&gt; SHIELD &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC1155&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;https:&#x2F;&#x2F;game.example&#x2F;api&#x2F;item&#x2F;{id}.json&amp;quot;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, GOLD,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;   10000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, SWORD,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;  1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;     &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, SHIELD,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;   &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The URI string contains &lt;code&gt;{id}&lt;&#x2F;code&gt;, which gets replaced by the token ID at query time. Token &lt;code&gt;0&lt;&#x2F;code&gt; resolves to &lt;code&gt;item&#x2F;0.json&lt;&#x2F;code&gt;, token &lt;code&gt;1&lt;&#x2F;code&gt; to &lt;code&gt;item&#x2F;1.json&lt;&#x2F;code&gt;, and so on. One URI template serves all tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;key-functions&quot;&gt;Key Functions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;minting&quot;&gt;Minting&lt;&#x2F;h3&gt;
&lt;p&gt;Single mint:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    _mint&lt;&#x2F;span&gt;&lt;span&gt;(to, id, amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Batch mint (this is where gas savings become significant):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mintBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    _mintBatch&lt;&#x2F;span&gt;&lt;span&gt;(to, ids, amounts,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Five tokens in one transaction instead of five.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transferring&quot;&gt;Transferring&lt;&#x2F;h3&gt;
&lt;p&gt;Single transfer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Batch transfer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; safeBatchTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;checking-balances&quot;&gt;Checking Balances&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Single balance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;Batch balance check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;function balanceOfBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; accounts&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ids&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The batch version lets you read multiple balances in a single call.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;approvals&quot;&gt;Approvals&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-1155 uses operator-level approval, not per-token approval:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Alice approves Bob to manage ALL her tokens in this contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;Check&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Bob is approved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;function isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;address account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; address operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is all-or-nothing. An approved operator can move any of your tokens in that contract. There is no way to approve access to only one token type. If you need that kind of granularity, ERC-721 per-token approvals are more appropriate.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Be careful which addresses you approve as operators. An approved operator can transfer any token you hold in that contract, not just a specific ID.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;transfer-flow&quot;&gt;Transfer Flow&lt;&#x2F;h2&gt;
&lt;p&gt;When a transfer is initiated, the contract runs through several checks before updating state:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;User initiates transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Has approval?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &#x2F;          \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; yes           no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |             |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Check balance  Revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enough tokens?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;         \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;yes          no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Update       Revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;balances&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Is receiver a contract?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;         \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; yes          no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Call receiver  Done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Receiver accepts?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &#x2F;         \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; yes          no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Done        Revert&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The last step matters. If the recipient is a contract, it must implement the receiver interface. Without it, the transfer reverts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;receiving-tokens-in-a-contract&quot;&gt;Receiving Tokens in a Contract&lt;&#x2F;h2&gt;
&lt;p&gt;If your contract needs to receive ERC-1155 tokens, implement &lt;code&gt;IERC1155Receiver&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;ItemVault.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC1155&#x2F;IERC1155Receiver.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ItemVault&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC1155Receiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onERC1155Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Handle single token receipt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.onERC1155Received.selector;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onERC1155BatchReceived&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; values&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.onERC1155BatchReceived.selector;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; supportsInterface&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; interfaceId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        external pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; interfaceId ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(IERC1155Receiver).interfaceId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Returning the correct selector signals to the sending contract that the receiver accepted the tokens intentionally. If you skip this interface, any &lt;code&gt;safeTransfer&lt;&#x2F;code&gt; to your contract will revert.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-real-example-rpg-crafting-system&quot;&gt;A Real Example: RPG Crafting System&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a more complete contract that lets you create token types on the fly and implement a crafting mechanic:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;RPGItems.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;@openzeppelin&#x2F;contracts&#x2F;token&#x2F;ERC1155&#x2F;ERC1155.sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; RPGItems&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ERC1155&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _currentTokenID &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; tokenSupply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span&gt; isNFT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ERC1155&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;https:&#x2F;&#x2F;rpg.game&#x2F;items&#x2F;{id}&amp;quot;) {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; createToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; supply&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; nft&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; id &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _currentTokenID;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;        _currentTokenID&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;        isNFT[id]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;       =&lt;&#x2F;span&gt;&lt;span&gt; nft;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;        tokenSupply[id]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; supply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, id, supply,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; id;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Burn a set of materials and mint the crafted result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; craft&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; materials&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; result&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; amounts &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; _ones&lt;&#x2F;span&gt;&lt;span&gt;(materials.length);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _burnBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, materials, amounts);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        _mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, result,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; _ones&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; length&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        private pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; amounts &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;            amounts[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; amounts;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;createToken&lt;&#x2F;code&gt; registers a new token type and mints the full supply to the caller. Pass &lt;code&gt;supply = 1&lt;&#x2F;code&gt; for an NFT, or any higher number for a fungible or semi-fungible token. &lt;code&gt;craft&lt;&#x2F;code&gt; burns a list of input materials and mints the output item. One transaction covers both sides of the operation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;metadata-structure&quot;&gt;Metadata Structure&lt;&#x2F;h2&gt;
&lt;p&gt;The JSON metadata for each token follows this structure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Fire Sword&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;description&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;A legendary blade forged in dragon fire&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;image&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;https:&#x2F;&#x2F;game.example&#x2F;images&#x2F;fire-sword.png&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;properties&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    &amp;quot;damage&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 150&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    &amp;quot;element&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;fire&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;    &amp;quot;rarity&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;legendary&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The contract URI template handles routing. You host one JSON file per token ID at the path your URI template describes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-savings-in-practice&quot;&gt;Gas Savings in Practice&lt;&#x2F;h2&gt;
&lt;p&gt;Transferring five different token types to one address:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;With separate ERC-20 &#x2F; ERC-721 contracts:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Transaction 1: Transfer token A  (21,000 base gas + execution)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Transaction 2: Transfer token B  (21,000 base gas + execution)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Transaction 3: Transfer token C  (21,000 base gas + execution)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Transaction 4: Transfer token D  (21,000 base gas + execution)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Transaction 5: Transfer token E  (21,000 base gas + execution)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Total base gas: ~105,000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;With ERC-1155 safeBatchTransferFrom:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Transaction 1: Transfer all 5   (21,000 base gas + batch execution)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Total base gas: ~21,000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The batch execution cost is higher than a single transfer, but the five separate base fees disappear. At scale, or when gas prices are elevated, this difference matters.&lt;&#x2F;p&gt;
&lt;p&gt;Minting is where the savings are even more dramatic. Minting 100 different token types with ERC-20 or ERC-721 requires 100 deployments plus 100 mint transactions. With ERC-1155, you deploy once and call &lt;code&gt;mintBatch&lt;&#x2F;code&gt; once.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;comparing-the-standards&quot;&gt;Comparing the Standards&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;&#x2F;th&gt;&lt;th&gt;ERC-20&lt;&#x2F;th&gt;&lt;th&gt;ERC-721&lt;&#x2F;th&gt;&lt;th&gt;ERC-1155&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Token types per contract&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;Unlimited&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Fungibility&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Both&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Batch transfers&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Gas efficiency&lt;&#x2F;td&gt;&lt;td&gt;Medium&lt;&#x2F;td&gt;&lt;td&gt;Medium&lt;&#x2F;td&gt;&lt;td&gt;High&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Per-token metadata&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Approval granularity&lt;&#x2F;td&gt;&lt;td&gt;Amount&lt;&#x2F;td&gt;&lt;td&gt;Per token&lt;&#x2F;td&gt;&lt;td&gt;Operator&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Best for&lt;&#x2F;td&gt;&lt;td&gt;Currency&lt;&#x2F;td&gt;&lt;td&gt;Unique assets&lt;&#x2F;td&gt;&lt;td&gt;Mixed assets&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;when-to-use-erc-20&quot;&gt;When to use ERC-20&lt;&#x2F;h3&gt;
&lt;p&gt;Use ERC-20 when you need one fungible token and maximum compatibility with DeFi protocols. Lending platforms, AMMs, and governance systems all expect ERC-20. Using ERC-1155 here adds complexity without benefit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-to-use-erc-721&quot;&gt;When to use ERC-721&lt;&#x2F;h3&gt;
&lt;p&gt;Use ERC-721 when every token must be unique and you want per-token approval control. Art platforms, domain name registries, and collectibles benefit from ERC-721&#x27;s tighter ownership semantics and broad marketplace support.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-to-use-erc-1155&quot;&gt;When to use ERC-1155&lt;&#x2F;h3&gt;
&lt;p&gt;Use ERC-1155 when you need multiple token types in one contract, especially when those types include both fungible and non-fungible tokens. Gaming inventories, digital item systems, and any application doing batch operations are the main use cases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-tradeoffs&quot;&gt;The Tradeoffs&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-1155 is flexible, but flexibility has a cost.&lt;&#x2F;p&gt;
&lt;p&gt;The operator approval model is coarser than ERC-721. You cannot approve an address to move only your swords but not your gold. Any operator gets full access to everything you hold in that contract. If approval granularity matters, this is a real limitation.&lt;&#x2F;p&gt;
&lt;p&gt;The balance mapping is two-dimensional. Tools, indexers, and wallets that were built for ERC-20 or ERC-721 do not automatically support ERC-1155. Marketplace support has improved significantly, but it is still not as universal as ERC-721 for NFTs.&lt;&#x2F;p&gt;
&lt;p&gt;There is also an argument for simplicity. A contract that manages one token type is easier to audit than one that manages hundreds. For a simple payment token, deploying ERC-1155 is unnecessary complexity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-1155 is the right standard when a single contract needs to manage multiple token types. It reduces deployment cost, cuts gas on batch operations, and handles fungible, non-fungible, and semi-fungible tokens without separate contracts for each.&lt;&#x2F;p&gt;
&lt;p&gt;For single-purpose tokens, ERC-20 and ERC-721 remain the cleaner choice. But for gaming, digital item systems, or any application mixing token types, ERC-1155 is the practical option.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ERC-20: The Standard That Powers Most Crypto Tokens</title>
        <published>2025-11-21T00:00:00+00:00</published>
        <updated>2025-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/erc-20-the-standard-that-powers-most-crypto-tokens/"/>
        <id>https://akash11.com/blog/erc-20-the-standard-that-powers-most-crypto-tokens/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/erc-20-the-standard-that-powers-most-crypto-tokens/">&lt;p&gt;ERC-20 is a technical standard that defines how tokens behave on Ethereum. It specifies a common interface so that any wallet, exchange, or smart contract can interact with any ERC-20 token without custom integration code.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers what ERC-20 requires, how each function and event works, the approve-and-transfer pattern used in DeFi, and the known weaknesses of the standard.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-erc-20-actually-is&quot;&gt;What ERC-20 Actually Is&lt;&#x2F;h2&gt;
&lt;p&gt;ERC stands for &quot;Ethereum Request for Comments&quot;. ERC-20 was proposed in November 2015 by Fabian Vogelsteller. Before this standard existed, every token on Ethereum had different function names and different behavior. Wallets and exchanges had to write custom code for each token they wanted to support. That was not scalable.&lt;&#x2F;p&gt;
&lt;p&gt;ERC-20 solved this by defining a minimal, shared interface. Any contract that implements the six required functions and two required events is an ERC-20 token. That is the entire requirement. The standard says nothing about what the token represents, who can hold it, or how it is created.&lt;&#x2F;p&gt;
&lt;p&gt;Today, the most widely used tokens on Ethereum follow this standard: USDT, USDC, LINK, UNI, and thousands of others.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-six-required-functions&quot;&gt;The Six Required Functions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;totalsupply&quot;&gt;&lt;code&gt;totalSupply()&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Returns the total number of tokens that exist.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If a token launched with 1 million tokens, this returns &lt;code&gt;1000000000000000000000000&lt;&#x2F;code&gt; (accounting for 18 decimals). More on decimals below.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;balanceof-address&quot;&gt;&lt;code&gt;balanceOf(address)&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Returns the number of tokens held by a specific address.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is how wallets display your token balance. Every balance query goes through this function.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transfer-address-uint256&quot;&gt;&lt;code&gt;transfer(address, uint256)&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Sends tokens from the caller&#x27;s address to another address.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The function must return &lt;code&gt;true&lt;&#x2F;code&gt; on success. It must revert (or return &lt;code&gt;false&lt;&#x2F;code&gt;) if the caller does not have enough tokens. It must also emit a &lt;code&gt;Transfer&lt;&#x2F;code&gt; event.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;approve-address-uint256&quot;&gt;&lt;code&gt;approve(address, uint256)&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Authorizes another address to spend tokens on your behalf, up to a specified amount.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the first step in the delegated transfer pattern used across DeFi. You are not moving tokens here. You are setting a permission. The actual transfer happens later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;allowance-address-address&quot;&gt;&lt;code&gt;allowance(address, address)&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Returns how many tokens a spender is still allowed to move on behalf of an owner.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After you approve a spender for 100 tokens and they transfer 40, &lt;code&gt;allowance(yourAddress, spenderAddress)&lt;&#x2F;code&gt; returns &lt;code&gt;60&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transferfrom-address-address-uint256&quot;&gt;&lt;code&gt;transferFrom(address, address, uint256)&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Transfers tokens from one address to another, using an existing allowance.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The caller of this function must have an allowance from &lt;code&gt;sender&lt;&#x2F;code&gt; that covers &lt;code&gt;amount&lt;&#x2F;code&gt;. This is what a DEX or lending protocol calls after you have approved it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-two-required-events&quot;&gt;The Two Required Events&lt;&#x2F;h2&gt;
&lt;p&gt;Events let off-chain applications track what happens on-chain without polling the blockchain constantly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transfer&quot;&gt;&lt;code&gt;Transfer&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Emitted whenever tokens move between addresses.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When new tokens are minted, &lt;code&gt;from&lt;&#x2F;code&gt; is the zero address. When tokens are burned, &lt;code&gt;to&lt;&#x2F;code&gt; is the zero address. This convention lets indexers detect minting and burning without additional logic.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;approval&quot;&gt;&lt;code&gt;Approval&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Emitted whenever &lt;code&gt;approve()&lt;&#x2F;code&gt; is called.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;a-minimal-working-implementation&quot;&gt;A Minimal Working Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a complete ERC-20 implementation with no external dependencies:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;SimpleToken.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SimpleToken&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; name &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Simple Token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; symbol &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;SMP&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; decimals &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _totalSupply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; _allowances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; initialSupply&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;        _totalSupply &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; initialSupply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;        _balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; initialSupply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Mint event: from is zero address&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, initialSupply);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _totalSupply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _balances[account];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(_balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;        _balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span&gt;        _balances[recipient]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, recipient, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;38&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;        _allowances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;][spender]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, spender, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; allowance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; spender&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; _allowances[owner][spender];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;49&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;51&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; recipient&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;52&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;53&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;54&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(_balances[sender] &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;55&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(_allowances[sender][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Allowance exceeded&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;56&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;57&lt;&#x2F;span&gt;&lt;span&gt;        _balances[sender]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;58&lt;&#x2F;span&gt;&lt;span&gt;        _balances[recipient]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;59&lt;&#x2F;span&gt;&lt;span&gt;        _allowances[sender][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;61&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(sender, recipient, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;62&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;63&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This contract is functional but not production-ready. For real deployments, use a battle-tested implementation like OpenZeppelin&#x27;s &lt;code&gt;ERC20.sol&lt;&#x2F;code&gt;, which handles edge cases this example skips.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;optional-metadata-functions&quot;&gt;Optional Metadata Functions&lt;&#x2F;h2&gt;
&lt;p&gt;The standard does not require these, but nearly every token includes them:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;function symbol&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;function decimals&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;decimals&lt;&#x2F;code&gt; value is important. Most tokens use &lt;code&gt;18&lt;&#x2F;code&gt;, matching Ether. This means that &lt;code&gt;1&lt;&#x2F;code&gt; token in human terms is stored as &lt;code&gt;1000000000000000000&lt;&#x2F;code&gt; in the contract. When you send &lt;code&gt;1.5 SMP&lt;&#x2F;code&gt;, you are actually passing &lt;code&gt;1500000000000000000&lt;&#x2F;code&gt; to &lt;code&gt;transfer()&lt;&#x2F;code&gt;. Your wallet handles this conversion so you do not have to.&lt;&#x2F;p&gt;
&lt;p&gt;Some tokens use different values. USDC uses &lt;code&gt;6&lt;&#x2F;code&gt; decimals. This is a design choice, not a mistake.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-approve-transferfrom-pattern&quot;&gt;The Approve-TransferFrom Pattern&lt;&#x2F;h2&gt;
&lt;p&gt;This two-step flow is used in every major DeFi protocol.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Step 1:&lt;&#x2F;strong&gt; You call &lt;code&gt;approve(dexAddress, amount)&lt;&#x2F;code&gt; on the token contract. This sets an allowance.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Step 2:&lt;&#x2F;strong&gt; The DEX calls &lt;code&gt;transferFrom(yourAddress, poolAddress, amount)&lt;&#x2F;code&gt; when you execute a trade.&lt;&#x2F;p&gt;
&lt;p&gt;Why two steps? Because the token contract must be the one to move funds. The DEX cannot take your tokens without your prior authorization. The approve step is that authorization.&lt;&#x2F;p&gt;
&lt;p&gt;In practice, many wallets prompt you to approve an unlimited amount (&lt;code&gt;type(uint256).max&lt;&#x2F;code&gt;) so you only pay the gas cost once. This is a UX tradeoff with real security implications: if the spender contract is ever exploited, all your approved tokens are at risk.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minting-and-burning&quot;&gt;Minting and Burning&lt;&#x2F;h2&gt;
&lt;p&gt;These operations are not in the ERC-20 standard, but most real tokens need them.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;MintBurn.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; account&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;    _totalSupply &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;    _balances[account]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; from = zero address signals a mint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;), account, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; burn&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(_balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    _balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    _totalSupply &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; to = zero address signals a burn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;), amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The convention of emitting &lt;code&gt;Transfer&lt;&#x2F;code&gt; with the zero address is not in the spec, but it is universally followed. Indexers and block explorers rely on it to correctly display total supply changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;known-weaknesses&quot;&gt;Known Weaknesses&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-approval-race-condition&quot;&gt;The Approval Race Condition&lt;&#x2F;h3&gt;
&lt;p&gt;Suppose you have approved a spender for 100 tokens. You then call &lt;code&gt;approve()&lt;&#x2F;code&gt; again to change it to 50. There is a window between your first transaction and the second where a watching spender can front-run you: spend the original 100 before the new approval lands, then spend 50 more after. Total damage: 150 tokens.&lt;&#x2F;p&gt;
&lt;p&gt;The safe mitigation is to set the allowance to &lt;code&gt;0&lt;&#x2F;code&gt; first, then set it to the new value in a second transaction.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;approve&lt;&#x2F;span&gt;&lt;span&gt;(spenderAddress,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;      &#x2F;&#x2F; First transaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;approve&lt;&#x2F;span&gt;&lt;span&gt;(spenderAddress,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Second transaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some protocols add &lt;code&gt;increaseAllowance&lt;&#x2F;code&gt; and &lt;code&gt;decreaseAllowance&lt;&#x2F;code&gt; helpers to make this cleaner, but these are also not part of the standard.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lost-tokens-in-contracts&quot;&gt;Lost Tokens in Contracts&lt;&#x2F;h3&gt;
&lt;p&gt;If you send ERC-20 tokens to a contract address that has no code to handle them, those tokens are stuck. The contract does not get notified that it received tokens. It cannot reject them. They are permanently inaccessible.&lt;&#x2F;p&gt;
&lt;p&gt;This is a real problem. Millions of dollars in tokens have been lost this way. ERC-223 and ERC-777 both tried to solve it by adding a callback mechanism, but neither gained the same adoption as ERC-20.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Always verify you are sending tokens to an address that can handle them. Sending ERC-20 tokens to a contract that has no withdrawal function results in permanent loss.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;no-transfer-notification&quot;&gt;No Transfer Notification&lt;&#x2F;h3&gt;
&lt;p&gt;Related to the above: contracts do not know when they receive ERC-20 tokens. If your contract needs to react to incoming tokens (trigger a swap, update accounting), you cannot rely on a callback. You have to build a separate deposit function that calls &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, or instruct users to call a function after transferring.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-erc-20-is-the-right-choice&quot;&gt;When ERC-20 Is the Right Choice&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-20 is the right choice when you need a fungible token that works everywhere Ethereum infrastructure exists: wallets, DEXs, bridges, lending protocols, and block explorers.&lt;&#x2F;p&gt;
&lt;p&gt;It is not the right choice when you need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Non-fungible tokens (use ERC-721 or ERC-1155)&lt;&#x2F;li&gt;
&lt;li&gt;Tokens with transfer hooks or callbacks (ERC-777 exists but has known reentrancy risks)&lt;&#x2F;li&gt;
&lt;li&gt;Gas-efficient multi-token contracts (ERC-1155 is better here)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The standard&#x27;s simplicity is also its main limitation. It does exactly what it specifies, nothing more. Any behavior beyond the six functions and two events is your responsibility to implement correctly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ERC-721: The Token Standard That Powers NFTs</title>
        <published>2025-11-21T00:00:00+00:00</published>
        <updated>2025-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/erc-721-the-token-standard-that-powers-nfts/"/>
        <id>https://akash11.com/blog/erc-721-the-token-standard-that-powers-nfts/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/erc-721-the-token-standard-that-powers-nfts/">&lt;p&gt;ERC-721 is the Ethereum token standard for non-fungible tokens. Each ERC-721 token is unique and indivisible. No two tokens are interchangeable, and you cannot split one into smaller units.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers how the standard works, what you must implement to be compliant, how metadata attaches to tokens, and how ERC-721 compares to ERC-20 and ERC-1155.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-non-fungible-means&quot;&gt;What Non-Fungible Means&lt;&#x2F;h2&gt;
&lt;p&gt;With ERC-20, all tokens are identical. One USDC is the same as any other USDC. You can add, subtract, and split them freely.&lt;&#x2F;p&gt;
&lt;p&gt;With ERC-721, token &lt;code&gt;#1&lt;&#x2F;code&gt; is completely different from token &lt;code&gt;#2&lt;&#x2F;code&gt;. Each has its own identity, its own owner, and its own value. You cannot send half a token. You transfer the whole thing or nothing.&lt;&#x2F;p&gt;
&lt;p&gt;This makes ERC-721 useful for representing things that are inherently unique: artworks, domain names, game items, event tickets, and certificates of ownership.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-core-interface&quot;&gt;The Core Interface&lt;&#x2F;h2&gt;
&lt;p&gt;Every ERC-721 contract must implement this interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC721&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; balanceOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; approve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getApproved&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; isApprovedForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is what each function does:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;balanceOf&lt;&#x2F;code&gt; returns the number of tokens an address owns. It is a count, not a value.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ownerOf&lt;&#x2F;code&gt; takes a token ID and returns the address that owns it. Every token has exactly one owner.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;transferFrom&lt;&#x2F;code&gt; moves a token from one address to another. The caller must be the owner or have approval.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;approve&lt;&#x2F;code&gt; lets you authorize a specific address to transfer a single token on your behalf.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;setApprovalForAll&lt;&#x2F;code&gt; grants an operator permission to manage all your tokens in one call.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;getApproved&lt;&#x2F;code&gt; and &lt;code&gt;isApprovedForAll&lt;&#x2F;code&gt; are the corresponding read functions to check those permissions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-basic-implementation&quot;&gt;A Basic Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a minimal contract showing how the core mechanics work:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;SimpleNFT.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SimpleNFT&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; owners;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; tokenApprovals;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; nextTokenId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mint&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; nextTokenId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        nextTokenId&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;        owners[tokenId]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; to;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;        balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; tokenId;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ownerOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; owners[tokenId];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(owner !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(owners[tokenId] == from,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Not the owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            msg.sender&lt;&#x2F;span&gt;&lt;span&gt; == from || tokenApprovals[tokenId] ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;            &amp;quot;Not approved&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;        balances[from]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;--&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;        balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;        owners[tokenId]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; to;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        delete&lt;&#x2F;span&gt;&lt;span&gt; tokenApprovals[tokenId];&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Clear approval after transfer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Three mappings power this contract. &lt;code&gt;owners&lt;&#x2F;code&gt; tracks which address holds each token ID. &lt;code&gt;balances&lt;&#x2F;code&gt; counts how many tokens each address owns. &lt;code&gt;tokenApprovals&lt;&#x2F;code&gt; stores per-token approvals.&lt;&#x2F;p&gt;
&lt;p&gt;Notice that &lt;code&gt;transferFrom&lt;&#x2F;code&gt; deletes the token approval at the end. This is required by the standard. Leaving stale approvals would let a previously approved address transfer a token after the owner has already moved it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;token-metadata&quot;&gt;Token Metadata&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-721 has an optional metadata extension. It adds three functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC721Metadata&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; symbol&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; tokenURI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;tokenURI&lt;&#x2F;code&gt; is the most important one. It returns a URL pointing to a JSON file that describes the token. The JSON follows a widely-adopted format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;My NFT #123&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;description&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;A unique digital item&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;image&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;ipfs:&#x2F;&#x2F;QmX7...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;  &amp;quot;attributes&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; &amp;quot;trait_type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Background&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; &amp;quot;value&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Blue&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; &amp;quot;trait_type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Rarity&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; &amp;quot;value&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Common&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Most projects store this JSON on IPFS rather than a centralized server. The smart contract stores only a hash or a base URI. The actual data lives off-chain.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-important&quot;&gt;
&lt;p&gt;The on-chain contract only stores a reference to the metadata, not the metadata itself. If the off-chain storage disappears, the metadata is gone. IPFS with pinning services is the standard approach for long-term availability.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;safe-transfers&quot;&gt;Safe Transfers&lt;&#x2F;h2&gt;
&lt;p&gt;Beyond &lt;code&gt;transferFrom&lt;&#x2F;code&gt;, the standard defines safe transfer functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; safeTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The difference from &lt;code&gt;transferFrom&lt;&#x2F;code&gt; is that these functions check whether the recipient can handle NFTs. If &lt;code&gt;to&lt;&#x2F;code&gt; is a contract, it must implement &lt;code&gt;IERC721Receiver&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC721Receiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onERC721Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes4&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the recipient contract does not implement this interface, the transfer reverts. This prevents tokens from getting permanently locked in contracts that have no way to move them.&lt;&#x2F;p&gt;
&lt;p&gt;When in doubt, prefer &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;. Use &lt;code&gt;transferFrom&lt;&#x2F;code&gt; only when you know the recipient can handle ERC-721 tokens.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;required-events&quot;&gt;Required Events&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-721 requires three events:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Approval&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; tokenId&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; approved&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All three fields in &lt;code&gt;Transfer&lt;&#x2F;code&gt; are indexed, which means external applications can filter by sender, recipient, or token ID individually. Marketplaces and wallets rely on these events to track ownership history without querying every block.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-optional-enumeration-extension&quot;&gt;The Optional Enumeration Extension&lt;&#x2F;h2&gt;
&lt;p&gt;The standard also defines an enumeration extension that lets you list tokens on-chain:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; IERC721Enumerable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; totalSupply&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; tokenByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; tokenOfOwnerByIndex&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; owner&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;tokenOfOwnerByIndex&lt;&#x2F;code&gt; lets you iterate over all tokens owned by a specific address. This is useful but expensive. It requires maintaining additional on-chain data structures, which increases gas costs on every mint and transfer. Many production contracts skip this extension and rely on off-chain indexers instead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;design-decisions-worth-thinking-about&quot;&gt;Design Decisions Worth Thinking About&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Token ID strategy.&lt;&#x2F;strong&gt; Sequential IDs (1, 2, 3...) are simple and predictable. Random IDs prevent MEV bots from front-running mints to claim low-numbered tokens, which some collectors prefer. Pick based on whether rarity or simplicity matters more to your project.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;On-chain vs off-chain data.&lt;&#x2F;strong&gt; Store as little as possible on-chain. Gas is expensive. Images, descriptions, and trait data belong off-chain. Only store what the contract logic actually needs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Batch minting.&lt;&#x2F;strong&gt; Minting tokens one at a time is expensive. If your contract lets users mint multiple tokens, implement batch minting in a single transaction to reduce gas costs.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Do not store large metadata blobs in contract storage. Every byte stored on-chain costs gas permanently. Even a moderately sized JSON object will make your contract expensive to deploy and interact with.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;erc-721-vs-erc-20&quot;&gt;ERC-721 vs ERC-20&lt;&#x2F;h2&gt;
&lt;p&gt;The core difference is fungibility. ERC-20 tokens are fungible and divisible. ERC-721 tokens are non-fungible and indivisible.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Property&lt;&#x2F;th&gt;&lt;th&gt;ERC-20&lt;&#x2F;th&gt;&lt;th&gt;ERC-721&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Fungible&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Divisible&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Identified by&lt;&#x2F;td&gt;&lt;td&gt;Amount&lt;&#x2F;td&gt;&lt;td&gt;Token ID&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;One owner per unit&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Approval granularity&lt;&#x2F;td&gt;&lt;td&gt;Spending amount&lt;&#x2F;td&gt;&lt;td&gt;Per-token or all-tokens&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The transfer calls reflect this difference directly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; ERC-20: transfer an amount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;token.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(recipient,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; ERC-721: transfer a specific token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;nft.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(owner, recipient,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The approval model is also different:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; ERC-20: approve a spending limit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;token.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;approve&lt;&#x2F;span&gt;&lt;span&gt;(spender,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; ERC-721: approve transfer of one specific token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;nft.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;approve&lt;&#x2F;span&gt;&lt;span&gt;(spender,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; ERC-721: approve an operator for all tokens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;nft.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;setApprovalForAll&lt;&#x2F;span&gt;&lt;span&gt;(operator,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Gas costs differ too. ERC-20 transfers update two balance values. ERC-721 transfers update an ownership mapping, update two balance counters, and clear an approval. ERC-721 transfers consistently cost more gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;erc-721-vs-erc-1155&quot;&gt;ERC-721 vs ERC-1155&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-1155 is a multi-token standard. One ERC-1155 contract can hold both fungible and non-fungible tokens at the same time. It also supports batch transfers in a single transaction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; ERC-1155: transfer multiple token types at once&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;safeBatchTransferFrom&lt;&#x2F;span&gt;&lt;span&gt;(from, to, [id1, id2, id3], [amount1, amount2, amount3], data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; ERC-721: requires one transaction per token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;nft.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(from, to, tokenId1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;nft.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(from, to, tokenId2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;nft.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span&gt;(from, to, tokenId3);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ERC-1155 is more gas-efficient when you need to move many tokens at once. It is also more flexible when a project needs both fungible items (currency, materials) and unique items (characters, land) in the same contract.&lt;&#x2F;p&gt;
&lt;p&gt;The tradeoff is complexity. ERC-1155 is harder to implement correctly and has less uniform support across wallets and marketplaces than ERC-721.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-to-use-each-standard&quot;&gt;When to Use Each Standard&lt;&#x2F;h2&gt;
&lt;p&gt;Pick ERC-20 when each unit is identical and you want divisibility. Currencies, governance tokens, and reward points belong here.&lt;&#x2F;p&gt;
&lt;p&gt;Pick ERC-721 when each item is unique and indivisible. Digital art, collectibles, domain names, and certificates of ownership are the right fit.&lt;&#x2F;p&gt;
&lt;p&gt;Pick ERC-1155 when you need both token types in the same system, or when batch operations matter for gas efficiency. Game inventories with weapons, currency, and unique characters are the typical use case.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-basics&quot;&gt;Security Basics&lt;&#x2F;h2&gt;
&lt;p&gt;A few checks every ERC-721 contract should have:&lt;&#x2F;p&gt;
&lt;p&gt;Verify a token exists before any operation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(owners[tokenId] !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Token does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Verify the caller has permission before any transfer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    msg.sender&lt;&#x2F;span&gt;&lt;span&gt; == owner ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;    tokenApprovals[tokenId] ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;    operatorApprovals[owner][&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;    &amp;quot;Not authorized&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Block transfers to the zero address:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(to !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Transfer to zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Use reentrancy guards on any function that calls external contracts, including &lt;code&gt;safeTransferFrom&lt;&#x2F;code&gt;. The callback to &lt;code&gt;onERC721Received&lt;&#x2F;code&gt; is an external call, and the recipient contract can execute arbitrary code before your function returns.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;ERC-721 gives you a clear, well-adopted way to create unique digital assets on Ethereum. The standard handles ownership tracking, transfer permissions, and safe transfer callbacks. Metadata stays off-chain. The on-chain contract stores references, not data.&lt;&#x2F;p&gt;
&lt;p&gt;It is not the most gas-efficient option and it lacks the batch capabilities of ERC-1155. But for projects where uniqueness is the core property, ERC-721 remains the default choice with the broadest support across tooling, wallets, and marketplaces.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Contract Creation in Solidity: CREATE, CREATE2, and CREATE3</title>
        <published>2025-11-17T00:00:00+00:00</published>
        <updated>2025-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/contract-creation-in-solidity-create-create2-and-create3/"/>
        <id>https://akash11.com/blog/contract-creation-in-solidity-create-create2-and-create3/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/contract-creation-in-solidity-create-create2-and-create3/">&lt;p&gt;Every contract deployed on Ethereum lives at an address. That address is not random. It is calculated deterministically from inputs that vary depending on which creation method you use.&lt;&#x2F;p&gt;
&lt;p&gt;There are three main ways to deploy a contract: &lt;code&gt;CREATE&lt;&#x2F;code&gt;, &lt;code&gt;CREATE2&lt;&#x2F;code&gt;, and &lt;code&gt;CREATE3&lt;&#x2F;code&gt;. Each calculates the address differently, and that difference has real consequences for how you architect cross-chain systems, factory contracts, and upgradeable deployments. This post explains how each method works, what it costs, and when to use it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-the-original-method&quot;&gt;CREATE: The Original Method&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;CREATE&lt;&#x2F;code&gt; has been part of Ethereum since genesis. The address of a contract deployed with &lt;code&gt;CREATE&lt;&#x2F;code&gt; is calculated like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract_address = keccak256(rlp([deployer_address, nonce]))[12:]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Two inputs determine the address:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The deployer&#x27;s address&lt;&#x2F;li&gt;
&lt;li&gt;The deployer&#x27;s nonce (total number of transactions sent from that address)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Here is a minimal example using &lt;code&gt;CREATE&lt;&#x2F;code&gt; through Solidity&#x27;s &lt;code&gt;new&lt;&#x2F;code&gt; keyword:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Factory.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.20&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SimpleContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Factory&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deploy&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        SimpleContract c &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; SimpleContract&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(c);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each time &lt;code&gt;deploy()&lt;&#x2F;code&gt; is called, the factory&#x27;s nonce increments and the resulting address changes. You cannot predict the address in advance unless you know the exact nonce at the time of deployment.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deploy 1: nonce = 5  -&amp;gt; address = 0xabc...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Deploy 2: nonce = 6  -&amp;gt; address = 0xdef...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is fine for simple use cases. But it creates a problem the moment you need the same address on two different chains or want to redeploy a contract to a known location.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;When to use CREATE:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Simple, single-chain deployments&lt;&#x2F;li&gt;
&lt;li&gt;Address predictability is not a requirement&lt;&#x2F;li&gt;
&lt;li&gt;You want the lowest possible deployment cost&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;create2-deterministic-deployment&quot;&gt;CREATE2: Deterministic Deployment&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;CREATE2&lt;&#x2F;code&gt; was introduced in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1014&quot;&gt;EIP-1014&lt;&#x2F;a&gt; to make contract addresses predictable before deployment. The formula changes to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract_address = keccak256(0xff ++ deployer_address ++ salt ++ keccak256(bytecode))[12:]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Four inputs now determine the address:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;0xff&lt;&#x2F;code&gt;: a constant prefix to prevent collisions with &lt;code&gt;CREATE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Deployer address&lt;&#x2F;li&gt;
&lt;li&gt;Salt: a &lt;code&gt;bytes32&lt;&#x2F;code&gt; value you choose&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;keccak256&lt;&#x2F;code&gt; of the contract&#x27;s creation bytecode&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Because you control the salt and you know your own address and the bytecode, you can compute the address before the contract exists.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Factory2.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.20&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SimpleContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Factory&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deploy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        SimpleContract c &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span&gt; SimpleContract{salt: salt}();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(c);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; computeAddress&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; bytecode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;(SimpleContract).creationCode;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt; hash &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;                bytes1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0xff&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;                address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;                salt,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;                keccak256&lt;&#x2F;span&gt;&lt;span&gt;(bytecode)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;            )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint160&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;(hash)));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;computeAddress&lt;&#x2F;code&gt; returns the exact address where the contract will land before you deploy it. This unlocks a pattern called counterfactual instantiation: other contracts can reference or send funds to an address before the contract at that address exists.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;CREATE2&lt;&#x2F;code&gt; also allows redeployment to the same address. If you deploy a contract, call &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; on it, then redeploy with the same salt and same bytecode, it lands at the same address again.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;&lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; behavior is subject to EIP proposals that may deprecate or restrict it in future network upgrades. Do not build critical systems that depend on &lt;code&gt;SELFDESTRUCT&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; redeployment without tracking EIP-6780 and related proposals.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The limitation of &lt;code&gt;CREATE2&lt;&#x2F;code&gt; is that the bytecode is part of the address calculation. If you want to deploy different code to the same address on different chains, you cannot do it with &lt;code&gt;CREATE2&lt;&#x2F;code&gt; alone.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;When to use CREATE2:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You need to predict a contract&#x27;s address before deploying it&lt;&#x2F;li&gt;
&lt;li&gt;You want the same address across chains, and you can guarantee identical bytecode&lt;&#x2F;li&gt;
&lt;li&gt;You are building counterfactual systems (payment channels, state channels, intent-based protocols)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;create3-address-independent-of-bytecode&quot;&gt;CREATE3: Address Independent of Bytecode&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;CREATE3&lt;&#x2F;code&gt; is not a native EVM opcode. It is a pattern that combines &lt;code&gt;CREATE2&lt;&#x2F;code&gt; and &lt;code&gt;CREATE&lt;&#x2F;code&gt; to separate address determination from contract bytecode. The result: the same salt produces the same address regardless of what code you deploy.&lt;&#x2F;p&gt;
&lt;p&gt;The mechanism works in two steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A factory deploys a minimal proxy using &lt;code&gt;CREATE2&lt;&#x2F;code&gt; with your chosen salt. This gives the proxy a deterministic address.&lt;&#x2F;li&gt;
&lt;li&gt;The proxy immediately deploys the actual contract using &lt;code&gt;CREATE&lt;&#x2F;code&gt;. Since the proxy is freshly created, its nonce is always &lt;code&gt;1&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Because the proxy address is determined by the salt alone (not the bytecode of the final contract), and the proxy&#x27;s nonce is always &lt;code&gt;1&lt;&#x2F;code&gt;, the final contract address depends only on your salt.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;final_address = keccak256(rlp([proxy_address, 1]))[12:]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is a simplified implementation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Factory3.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.20&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Proxy&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deploy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; code&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; addr&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        assembly&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;            addr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(code,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0x20&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(code))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(addr !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Deployment failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Factory&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deploy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; code&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Step 1: deploy proxy deterministically with CREATE2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; proxy &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt; Proxy{salt: salt}());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Step 2: proxy deploys actual contract with CREATE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Proxy&lt;&#x2F;span&gt;&lt;span&gt;(proxy).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;deploy&lt;&#x2F;span&gt;&lt;span&gt;(code);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; addressOf&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; salt&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Predict proxy address using CREATE2 formula&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes32&lt;&#x2F;span&gt;&lt;span&gt; proxyHash &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;= keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;(Proxy).creationCode);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; proxy &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint160&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0xff&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;), salt, proxyHash)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span&gt;        ))));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Proxy nonce is always 1 for first deployment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint160&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;keccak256&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodePacked&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0xd6&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0x94&lt;&#x2F;span&gt;&lt;span&gt;), proxy,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0x01&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;        ))));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
&lt;p&gt;In production, use an audited &lt;code&gt;CREATE3&lt;&#x2F;code&gt; library such as &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Vectorized&#x2F;solady&#x2F;blob&#x2F;main&#x2F;src&#x2F;utils&#x2F;CREATE3.sol&quot;&gt;solady&#x27;s &lt;code&gt;CREATE3&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;transmissions11&#x2F;solmate&#x2F;blob&#x2F;main&#x2F;src&#x2F;utils&#x2F;CREATE3.sol&quot;&gt;transmissions11&#x2F;solmate&lt;&#x2F;a&gt; rather than rolling your own. The proxy bytecode must be exact and stable.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The cost of &lt;code&gt;CREATE3&lt;&#x2F;code&gt; is higher than both &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; because two deployments happen for every contract: one for the proxy, one for the actual contract.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;When to use CREATE3:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You need the same address across chains and you cannot guarantee identical bytecode (different compiler versions, different constructor arguments encoded into bytecode, intentional code differences)&lt;&#x2F;li&gt;
&lt;li&gt;You want a clean address registry where a single salt always resolves to the same address regardless of what is deployed there&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;side-by-side-comparison&quot;&gt;Side-by-Side Comparison&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;CREATE&lt;&#x2F;th&gt;&lt;th&gt;CREATE2&lt;&#x2F;th&gt;&lt;th&gt;CREATE3&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Address depends on&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;deployer&lt;&#x2F;code&gt;, &lt;code&gt;nonce&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;deployer&lt;&#x2F;code&gt;, &lt;code&gt;salt&lt;&#x2F;code&gt;, &lt;code&gt;bytecode&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;deployer&lt;&#x2F;code&gt;, &lt;code&gt;salt&lt;&#x2F;code&gt; only&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Predictable before deploy&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Same address across chains&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes, if bytecode matches&lt;&#x2F;td&gt;&lt;td&gt;Yes, always&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Can redeploy to same address&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes (requires SELFDESTRUCT)&lt;&#x2F;td&gt;&lt;td&gt;No (proxy nonce increments)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Gas cost&lt;&#x2F;td&gt;&lt;td&gt;Lowest&lt;&#x2F;td&gt;&lt;td&gt;Low&lt;&#x2F;td&gt;&lt;td&gt;Higher (two deployments)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Native EVM support&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;No (pattern only)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;cross-chain-address-example&quot;&gt;Cross-Chain Address Example&lt;&#x2F;h2&gt;
&lt;p&gt;This is the scenario where the choice matters most. You are deploying the same protocol to Ethereum and Arbitrum.&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;code&gt;CREATE&lt;&#x2F;code&gt;, the nonce on each chain may differ. You get different addresses.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ethereum: deployer nonce = 5 -&amp;gt; 0xabc...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Arbitrum: deployer nonce = 3 -&amp;gt; 0xdef...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With &lt;code&gt;CREATE2&lt;&#x2F;code&gt;, same salt and same bytecode means same address. But if your bytecode differs at all, the address changes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ethereum: salt=X, bytecode=Y -&amp;gt; 0x123...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Arbitrum: salt=X, bytecode=Y -&amp;gt; 0x123...  (same)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Arbitrum: salt=X, bytecode=Z -&amp;gt; 0x456...  (different!)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With &lt;code&gt;CREATE3&lt;&#x2F;code&gt;, the bytecode is irrelevant to the address. Only the salt and the factory address matter.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ethereum: salt=X -&amp;gt; 0x789... (any bytecode)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Arbitrum: salt=X -&amp;gt; 0x789... (any bytecode)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is why protocols that deploy across many chains often build their own &lt;code&gt;CREATE3&lt;&#x2F;code&gt; factory, deployed to the same address on each chain using &lt;code&gt;CREATE2&lt;&#x2F;code&gt;, then use that factory for all subsequent deployments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;choosing-the-right-method&quot;&gt;Choosing the Right Method&lt;&#x2F;h2&gt;
&lt;p&gt;The decision comes down to two questions: do you need predictability, and do you need bytecode independence?&lt;&#x2F;p&gt;
&lt;p&gt;If predictability is not needed, use &lt;code&gt;CREATE&lt;&#x2F;code&gt;. It is the cheapest and simplest option.&lt;&#x2F;p&gt;
&lt;p&gt;If you need predictability and can guarantee identical bytecode across deployments, use &lt;code&gt;CREATE2&lt;&#x2F;code&gt;. It is cheaper than &lt;code&gt;CREATE3&lt;&#x2F;code&gt; and natively supported by the EVM.&lt;&#x2F;p&gt;
&lt;p&gt;If you need predictability but cannot guarantee identical bytecode, use &lt;code&gt;CREATE3&lt;&#x2F;code&gt;. Accept the extra gas cost in exchange for a stable address registry that is independent of your implementation details.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>msg.sender vs tx.origin in Solidity</title>
        <published>2025-11-09T00:00:00+00:00</published>
        <updated>2025-11-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/msg-sender-vs-txorigin-in-solidity/"/>
        <id>https://akash11.com/blog/msg-sender-vs-txorigin-in-solidity/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/msg-sender-vs-txorigin-in-solidity/">&lt;p&gt;Solidity gives you two built-in variables to identify who is calling your contract: &lt;code&gt;msg.sender&lt;&#x2F;code&gt; and &lt;code&gt;tx.origin&lt;&#x2F;code&gt;. They look similar, but they track different things. Picking the wrong one for access control is one of the most common and exploitable mistakes in Solidity code.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains what each variable does, how they differ in a multi-contract call chain, and why &lt;code&gt;tx.origin&lt;&#x2F;code&gt; is dangerous for authentication.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-each-variable-tracks&quot;&gt;What Each Variable Tracks&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; is the &lt;strong&gt;immediate caller&lt;&#x2F;strong&gt; of the current function. If a user calls your contract directly, &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is the user&#x27;s address. If another contract calls your contract, &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is that contract&#x27;s address. It changes at every step in the call chain.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;tx.origin&lt;&#x2F;code&gt; is the &lt;strong&gt;original transaction signer&lt;&#x2F;strong&gt;. It always points to the externally owned account (EOA) that signed and submitted the transaction, no matter how many contracts are involved in the call chain. It never changes within a transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-the-call-chain-changes-msg-sender&quot;&gt;How the Call Chain Changes msg.sender&lt;&#x2F;h2&gt;
&lt;p&gt;Consider this call sequence:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;User (0xUser)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Contract A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Contract B&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Inside &lt;code&gt;Contract B&lt;&#x2F;code&gt;, the two variables resolve to different addresses:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; = address of &lt;code&gt;Contract A&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tx.origin&lt;&#x2F;code&gt; = &lt;code&gt;0xUser&lt;&#x2F;code&gt; (the original EOA)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This difference is subtle, but it has serious security consequences.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a minimal contract that records both values:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;CallerInfo.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; CallerInfo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; lastSender;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; lastOrigin;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; recordCaller&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        lastSender &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        lastOrigin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; tx&lt;&#x2F;span&gt;&lt;span&gt;.origin;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Intermediary&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; callThroughMe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        CallerInfo&lt;&#x2F;span&gt;&lt;span&gt;(target).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;recordCaller&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If a user at &lt;code&gt;0xUser&lt;&#x2F;code&gt; calls &lt;code&gt;Intermediary.callThroughMe()&lt;&#x2F;code&gt;, which then calls &lt;code&gt;CallerInfo.recordCaller()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;lastSender&lt;&#x2F;code&gt; will hold the address of the &lt;code&gt;Intermediary&lt;&#x2F;code&gt; contract&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;lastOrigin&lt;&#x2F;code&gt; will hold &lt;code&gt;0xUser&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-security-problem-with-tx-origin&quot;&gt;The Security Problem with tx.origin&lt;&#x2F;h2&gt;
&lt;p&gt;Using &lt;code&gt;tx.origin&lt;&#x2F;code&gt; for authentication creates a phishing vulnerability. Any contract that tricks the real owner into calling it can drain funds from your wallet.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a vulnerable wallet:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Wallet.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Wallet&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;.origin == owner,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; vulnerable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        payable&lt;&#x2F;span&gt;&lt;span&gt;(to).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An attacker deploys this malicious contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Attack.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Attack&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;    Wallet &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span&gt; wallet;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; attacker;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _wallet&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        wallet &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Wallet&lt;&#x2F;span&gt;&lt;span&gt;(_wallet);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        attacker &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; attack&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Calls the wallet on behalf of whoever calls this function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;        wallet.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(attacker,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(wallet).balance);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The attack works like this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The attacker shares the &lt;code&gt;Attack&lt;&#x2F;code&gt; contract with the wallet owner (through a phishing site, a malicious airdrop, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;The owner calls &lt;code&gt;Attack.attack()&lt;&#x2F;code&gt;, thinking they are interacting with some other protocol&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Attack.attack()&lt;&#x2F;code&gt; calls &lt;code&gt;Wallet.transfer()&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Inside &lt;code&gt;Wallet.transfer()&lt;&#x2F;code&gt;, the check &lt;code&gt;tx.origin == owner&lt;&#x2F;code&gt; passes because the owner did sign the original transaction&lt;&#x2F;li&gt;
&lt;li&gt;Funds are sent to the attacker&#x27;s address&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Owner (tx.origin = owner)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | tricked into calling&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Attack.attack()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Wallet.transfer()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | require(tx.origin == owner) passes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Funds drained&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The wallet never knew the owner did not directly authorize this transfer. It only checked who signed the transaction, not who actually called the function.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Never use &lt;code&gt;tx.origin&lt;&#x2F;code&gt; as the sole check for ownership or authorization. Any intermediate contract in the call chain can exploit it.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;the-fix-use-msg-sender&quot;&gt;The Fix: Use msg.sender&lt;&#x2F;h2&gt;
&lt;p&gt;Replace &lt;code&gt;tx.origin&lt;&#x2F;code&gt; with &lt;code&gt;msg.sender&lt;&#x2F;code&gt; in the access control check:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;SafeWallet.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SafeWallet&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; == owner,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; safe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        payable&lt;&#x2F;span&gt;&lt;span&gt;(to).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The same attack now fails:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Attack.attack()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | calls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SafeWallet.transfer()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | require(msg.sender == owner) fails&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    | (msg.sender is the Attack contract, not the owner)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Transaction reverts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because &lt;code&gt;msg.sender&lt;&#x2F;code&gt; is the &lt;code&gt;Attack&lt;&#x2F;code&gt; contract&#x27;s address, not the owner&#x27;s address, the require check rejects the call.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-tx-origin-is-acceptable&quot;&gt;When tx.origin Is Acceptable&lt;&#x2F;h2&gt;
&lt;p&gt;There are narrow, non-security use cases where &lt;code&gt;tx.origin&lt;&#x2F;code&gt; is useful:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Gas tracking in relay contracts.&lt;&#x2F;strong&gt; If you are building a meta-transaction relay, you might want to track gas usage by the original end user rather than the relay itself:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;GasRelay.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; GasRelay&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; userGasSpent;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; relayCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; target&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint&lt;&#x2F;span&gt;&lt;span&gt; gasBefore &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; gasleft&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success,)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; target.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Call failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Track gas by the original user, not this relay contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        userGasSpent[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;tx&lt;&#x2F;span&gt;&lt;span&gt;.origin]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; gasBefore &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; gasleft&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here &lt;code&gt;tx.origin&lt;&#x2F;code&gt; is used only for bookkeeping. The actual access control inside &lt;code&gt;target&lt;&#x2F;code&gt; still uses &lt;code&gt;msg.sender&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Analytics and event logging.&lt;&#x2F;strong&gt; If you want to emit an event that records who ultimately initiated a batch of calls, &lt;code&gt;tx.origin&lt;&#x2F;code&gt; lets you capture the end user&#x27;s address.&lt;&#x2F;p&gt;
&lt;p&gt;In both cases, &lt;code&gt;tx.origin&lt;&#x2F;code&gt; is supplemental information, not a security gate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quick-reference&quot;&gt;Quick Reference&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Use case&lt;&#x2F;th&gt;&lt;th&gt;Use&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Ownership checks&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Access control and permissions&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Transferring funds or tokens&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Any security-critical check&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Logging the originating EOA&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;tx.origin&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Gas tracking in relays&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;tx.origin&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Meta-transaction patterns (non-auth)&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;tx.origin&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt; reflects the direct caller of your function. &lt;code&gt;tx.origin&lt;&#x2F;code&gt; reflects the EOA that started the entire transaction. For any access control or ownership check, always use &lt;code&gt;msg.sender&lt;&#x2F;code&gt;. Using &lt;code&gt;tx.origin&lt;&#x2F;code&gt; for authentication lets a malicious contract impersonate the real user simply by getting them to call it, even once. Reserve &lt;code&gt;tx.origin&lt;&#x2F;code&gt; for analytics or tracking purposes where security is not at stake.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Call and Delegatecall in Solidity</title>
        <published>2025-11-08T00:00:00+00:00</published>
        <updated>2025-11-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/call-and-delegatecall-in-solidity/"/>
        <id>https://akash11.com/blog/call-and-delegatecall-in-solidity/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/call-and-delegatecall-in-solidity/">&lt;p&gt;Solidity gives you regular function calls for most contract-to-contract interactions. But two low-level functions, &lt;code&gt;call&lt;&#x2F;code&gt; and &lt;code&gt;delegatecall&lt;&#x2F;code&gt;, let you go further. They bypass the usual function call safety checks and give you direct control over how code runs and where state is stored.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains what each function does, how they differ, when to use them, and what can go wrong.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-call-does&quot;&gt;What call Does&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;call&lt;&#x2F;code&gt; is a low-level function that triggers a function on another contract. The code runs in the target contract&#x27;s context. That means the target contract&#x27;s storage gets modified, the target&#x27;s address is used as &lt;code&gt;this&lt;&#x2F;code&gt;, and any Ether sent goes to the target&#x27;s balance.&lt;&#x2F;p&gt;
&lt;p&gt;Basic syntax:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; data)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; targetAddress.call{value: amount}(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;functionName(uint256)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, argument)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The function returns two values. &lt;code&gt;success&lt;&#x2F;code&gt; is &lt;code&gt;true&lt;&#x2F;code&gt; if the call worked and &lt;code&gt;false&lt;&#x2F;code&gt; if it failed. &lt;code&gt;data&lt;&#x2F;code&gt; holds the return value from the called function.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a working example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;call-example.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Receiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; setValue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        value &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Caller&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; callSetValue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _receiver&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _receiver.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;setValue(uint256)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, _value)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Call failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When &lt;code&gt;Caller&lt;&#x2F;code&gt; uses &lt;code&gt;call&lt;&#x2F;code&gt; to trigger &lt;code&gt;setValue&lt;&#x2F;code&gt;, the &lt;code&gt;value&lt;&#x2F;code&gt; variable inside &lt;code&gt;Receiver&lt;&#x2F;code&gt; gets updated. The Ether sent goes to &lt;code&gt;Receiver&lt;&#x2F;code&gt;&#x27;s balance. &lt;code&gt;Caller&lt;&#x2F;code&gt; is not affected.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;when-to-use-call&quot;&gt;When to Use call&lt;&#x2F;h3&gt;
&lt;p&gt;Use &lt;code&gt;call&lt;&#x2F;code&gt; in these situations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Sending Ether to an address. It is the recommended method since &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;send&lt;&#x2F;code&gt; have a fixed gas stipend that can cause failures.&lt;&#x2F;li&gt;
&lt;li&gt;Interacting with a contract you do not have the interface or ABI for.&lt;&#x2F;li&gt;
&lt;li&gt;Building generic contract interactions where you need to forward all remaining gas.&lt;&#x2F;li&gt;
&lt;li&gt;Implementing proxy patterns.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;send-ether.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SendEther&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendViaCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; sent, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _to.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(sent,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Failed to send Ether&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;&lt;code&gt;call&lt;&#x2F;code&gt; does not revert automatically on failure. Always check the &lt;code&gt;success&lt;&#x2F;code&gt; boolean and handle failures explicitly. Ignoring it is a common source of bugs.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;what-delegatecall-does&quot;&gt;What delegatecall Does&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;delegatecall&lt;&#x2F;code&gt; runs another contract&#x27;s code inside your contract&#x27;s context. The target contract provides the logic, but your contract&#x27;s storage, address, and balance are used. The &lt;code&gt;msg.sender&lt;&#x2F;code&gt; and &lt;code&gt;msg.value&lt;&#x2F;code&gt; from the original transaction are also preserved.&lt;&#x2F;p&gt;
&lt;p&gt;This is the key distinction: &lt;code&gt;call&lt;&#x2F;code&gt; runs code in the target&#x27;s world, while &lt;code&gt;delegatecall&lt;&#x2F;code&gt; borrows the target&#x27;s code and runs it in your world.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;call:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Caller --&amp;gt; Target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             Target&amp;#39;s storage is modified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             Target&amp;#39;s address is `this`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;delegatecall:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Caller --&amp;gt; borrows Target&amp;#39;s code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Caller&amp;#39;s storage is modified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Caller&amp;#39;s address is `this`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is a basic example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;delegatecall-example.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Logic&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; number;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; setNumber&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _number&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        number &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _number;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Storage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; number;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; delegateSetNumber&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _logic&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _number&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _logic.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delegatecall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;setNumber(uint256)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, _number)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Delegatecall failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When &lt;code&gt;Storage&lt;&#x2F;code&gt; calls &lt;code&gt;delegateSetNumber&lt;&#x2F;code&gt;, it runs &lt;code&gt;Logic.setNumber&lt;&#x2F;code&gt; using &lt;code&gt;delegatecall&lt;&#x2F;code&gt;. The &lt;code&gt;number&lt;&#x2F;code&gt; variable in &lt;code&gt;Storage&lt;&#x2F;code&gt; gets updated, not the one in &lt;code&gt;Logic&lt;&#x2F;code&gt;. The code from &lt;code&gt;Logic&lt;&#x2F;code&gt; runs, but it operates on &lt;code&gt;Storage&lt;&#x2F;code&gt;&#x27;s data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;storage-layout-must-match&quot;&gt;Storage Layout Must Match&lt;&#x2F;h3&gt;
&lt;p&gt;This is the most important rule when using &lt;code&gt;delegatecall&lt;&#x2F;code&gt;. The calling contract and the logic contract must declare their state variables in the same order.&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;code&gt;delegatecall&lt;&#x2F;code&gt; writes to &lt;code&gt;number&lt;&#x2F;code&gt;, it writes to slot 0 in storage. It does not know the variable name. It only knows the slot number.&lt;&#x2F;p&gt;
&lt;p&gt;Matching layout (correct):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;matching-layout.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; num;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; sender;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; slot 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; B&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; num;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; sender;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; slot 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; setVars&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _num&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        num &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _num;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;        sender &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Mismatched layout (dangerous):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;mismatched-layout.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; slot 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; B&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; slot 0 -- mismatched&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; slot 1 -- mismatched&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you use &lt;code&gt;delegatecall&lt;&#x2F;code&gt; between &lt;code&gt;A&lt;&#x2F;code&gt; and &lt;code&gt;B&lt;&#x2F;code&gt; in the mismatched example, writing to &lt;code&gt;value&lt;&#x2F;code&gt; in the logic contract writes to slot 0 in &lt;code&gt;A&lt;&#x2F;code&gt;. That overwrites &lt;code&gt;owner&lt;&#x2F;code&gt;. Your storage gets corrupted silently.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-caution&quot;&gt;
&lt;p&gt;Storage layout mismatch with &lt;code&gt;delegatecall&lt;&#x2F;code&gt; does not throw an error. The transaction succeeds, but the wrong variables get overwritten. This is one of the most dangerous bugs in Solidity.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;the-proxy-pattern&quot;&gt;The Proxy Pattern&lt;&#x2F;h2&gt;
&lt;p&gt;The most common use of &lt;code&gt;delegatecall&lt;&#x2F;code&gt; in production is the upgradeable proxy pattern. The idea: users interact with a proxy contract, but the actual logic lives in a separate implementation contract. You can upgrade the contract by pointing the proxy to a new implementation, without changing the address users interact with.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;proxy.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Proxy&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; implementation;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;          &#x2F;&#x2F; slot 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _implementation&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        implementation &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _implementation;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; impl &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; implementation;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        assembly&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;            calldatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; calldatasize&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;:=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; delegatecall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;gas&lt;&#x2F;span&gt;&lt;span&gt;(), impl,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; calldatasize&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;            returndatacopy&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;            switch result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;            case &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;()) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;            default {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; returndatasize&lt;&#x2F;span&gt;&lt;span&gt;()) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Implementation&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; implementation;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; slot 0 -- must match Proxy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;          &#x2F;&#x2F; slot 1 -- must match Proxy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; setValue&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span&gt;        value &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Any call to &lt;code&gt;Proxy&lt;&#x2F;code&gt; that does not match a defined function falls through to the &lt;code&gt;fallback&lt;&#x2F;code&gt;, which forwards the call to &lt;code&gt;Implementation&lt;&#x2F;code&gt; using &lt;code&gt;delegatecall&lt;&#x2F;code&gt;. The proxy&#x27;s storage is modified, not the implementation&#x27;s.&lt;&#x2F;p&gt;
&lt;p&gt;To upgrade, deploy a new implementation contract and update &lt;code&gt;implementation&lt;&#x2F;code&gt; in the proxy. Users never need to change the address they call.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
&lt;p&gt;Real-world proxy patterns like OpenZeppelin&#x27;s UUPS and Transparent Proxy use more sophisticated storage slot management (EIP-1967) to avoid layout collisions between proxy admin variables and logic variables.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;key-differences-side-by-side&quot;&gt;Key Differences Side by Side&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Property&lt;&#x2F;th&gt;&lt;th&gt;call&lt;&#x2F;th&gt;&lt;th&gt;delegatecall&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;msg.sender&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Calling contract&#x27;s address&lt;&#x2F;td&gt;&lt;td&gt;Original transaction sender&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;msg.value&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Value sent with the call&lt;&#x2F;td&gt;&lt;td&gt;Original transaction value&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;this&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Target contract&lt;&#x2F;td&gt;&lt;td&gt;Calling contract&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Storage modified&lt;&#x2F;td&gt;&lt;td&gt;Target contract&#x27;s storage&lt;&#x2F;td&gt;&lt;td&gt;Calling contract&#x27;s storage&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Typical use&lt;&#x2F;td&gt;&lt;td&gt;Sending Ether, generic calls&lt;&#x2F;td&gt;&lt;td&gt;Proxy patterns, upgradeable contracts&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;security-the-difference-matters&quot;&gt;Security: The Difference Matters&lt;&#x2F;h2&gt;
&lt;p&gt;The distinction between &lt;code&gt;call&lt;&#x2F;code&gt; and &lt;code&gt;delegatecall&lt;&#x2F;code&gt; has direct security implications. Consider this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;security-example.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Target&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; changeOwner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _newOwner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _newOwner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Victim&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; doCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; call: changes Target&amp;#39;s owner, Victim is unaffected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; s1, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _target.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;changeOwner(address)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; delegatecall: changes Victim&amp;#39;s owner, Target is unaffected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; s2, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _target.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;delegatecall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;changeOwner(address)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;call&lt;&#x2F;code&gt; version modifies &lt;code&gt;Target.owner&lt;&#x2F;code&gt;. The &lt;code&gt;delegatecall&lt;&#x2F;code&gt; version modifies &lt;code&gt;Victim.owner&lt;&#x2F;code&gt;. If an attacker controls the logic contract passed to a &lt;code&gt;delegatecall&lt;&#x2F;code&gt;, they can overwrite any storage slot in your contract, including ownership and access control variables.&lt;&#x2F;p&gt;
&lt;p&gt;Never use &lt;code&gt;delegatecall&lt;&#x2F;code&gt; with an untrusted address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;error-handling&quot;&gt;Error Handling&lt;&#x2F;h2&gt;
&lt;p&gt;Neither &lt;code&gt;call&lt;&#x2F;code&gt; nor &lt;code&gt;delegatecall&lt;&#x2F;code&gt; reverts automatically on failure. Both return a &lt;code&gt;success&lt;&#x2F;code&gt; boolean. If you ignore it, your contract continues executing after a failed call, which leads to subtle and hard-to-debug bugs.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;error-handling.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ErrorHandler&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; safeCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; returnData)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; target.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;someFunction()&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (!success) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (returnData.length &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;                &#x2F;&#x2F; Bubble up the revert reason from the failed call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                assembly&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                    revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(returnData,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; mload&lt;&#x2F;span&gt;&lt;span&gt;(returnData))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;                revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;Call failed without reason&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The assembly block re-throws the original revert reason from the failed call. Without it, you lose the reason and get a generic error instead.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-forwarding&quot;&gt;Gas Forwarding&lt;&#x2F;h2&gt;
&lt;p&gt;Before Solidity 0.6.2, you had to manually specify gas when using &lt;code&gt;call&lt;&#x2F;code&gt;. Now it forwards all available gas by default. You can still override this when needed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Forwards all available gas (default since 0.6.2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;target.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Forwards all gas with Ether&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;target.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1 ether&lt;&#x2F;span&gt;&lt;span&gt;}(data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Explicit gas limit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;target.call{gas:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;}(data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Forwarding all gas is usually what you want. Setting an explicit gas limit can cause calls to fail if the target needs more gas than you allowed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-practical-pattern-multicall&quot;&gt;A Practical Pattern: MultiCall&lt;&#x2F;h2&gt;
&lt;p&gt;One common real-world use of &lt;code&gt;call&lt;&#x2F;code&gt; is batching multiple contract interactions into a single transaction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;multicall.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; MultiCall&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; multiCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; targets&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(targets.length == data.length,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Length mismatch&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bytes&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; results &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;targets&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; targets.length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; result)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; targets[i].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span&gt;(data[i]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Call failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;            results[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; result;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; results;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This pattern is used in DeFi protocols to batch reads or writes, reducing the number of round trips from the client.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Use &lt;code&gt;call&lt;&#x2F;code&gt; for standard contract interactions, sending Ether, and interacting with contracts you do not have an interface for. It runs code in the target&#x27;s context and keeps your state isolated.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;code&gt;delegatecall&lt;&#x2F;code&gt; when you need to borrow logic from another contract while keeping state in your own contract. The proxy upgrade pattern is the primary use case. When you use it, storage layout between contracts must match exactly, and the logic contract must be trusted code you control.&lt;&#x2F;p&gt;
&lt;p&gt;Both functions skip automatic revert on failure. Always check the returned &lt;code&gt;success&lt;&#x2F;code&gt; value.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fallback Functions in Solidity</title>
        <published>2025-11-05T00:00:00+00:00</published>
        <updated>2025-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/fallback-functions-in-solidity/"/>
        <id>https://akash11.com/blog/fallback-functions-in-solidity/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/fallback-functions-in-solidity/">&lt;p&gt;Solidity has two special functions that handle incoming transactions your contract did not explicitly plan for: &lt;code&gt;receive()&lt;&#x2F;code&gt; and &lt;code&gt;fallback()&lt;&#x2F;code&gt;. They look similar, but they serve different purposes. This post explains what each function does, how Solidity decides which one to call, and how to use them correctly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-solidity-routes-incoming-transactions&quot;&gt;How Solidity Routes Incoming Transactions&lt;&#x2F;h2&gt;
&lt;p&gt;When a transaction arrives at your contract, Solidity runs through a decision tree before executing any code.&lt;&#x2F;p&gt;
&lt;p&gt;First, it checks whether &lt;code&gt;msg.data&lt;&#x2F;code&gt; is empty.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;msg.data&lt;&#x2F;code&gt; is empty, Solidity looks for a &lt;code&gt;receive()&lt;&#x2F;code&gt; function. If one exists, it runs. If not, Solidity falls back to &lt;code&gt;fallback()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;msg.data&lt;&#x2F;code&gt; is not empty, Solidity skips &lt;code&gt;receive()&lt;&#x2F;code&gt; entirely and goes straight to &lt;code&gt;fallback()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is that logic as a diagram:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         incoming transaction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        msg.data is empty?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           &#x2F;           \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         yes             no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          |               |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  receive() exists?    fallback()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &#x2F;        \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    yes          no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     |            |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; receive()     fallback()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The separation is intentional. Plain Ether transfers have no data. Function calls and other interactions do. This lets you handle each case with different logic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-two-functions&quot;&gt;The Two Functions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;receive&quot;&gt;receive()&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;receive()&lt;&#x2F;code&gt; handles plain Ether transfers. When someone sends Ether to your contract without calling any function, this is what runs.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ReceiveExample&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;receive()&lt;&#x2F;code&gt; must be &lt;code&gt;external&lt;&#x2F;code&gt; and &lt;code&gt;payable&lt;&#x2F;code&gt;. It takes no parameters and returns nothing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fallback&quot;&gt;fallback()&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;fallback()&lt;&#x2F;code&gt; is the catch-all. It runs when someone calls a function that does not exist on your contract, or when Ether arrives with data but no &lt;code&gt;receive()&lt;&#x2F;code&gt; function is defined.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FallbackExample&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FallbackCalled&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; FallbackCalled&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Like &lt;code&gt;receive()&lt;&#x2F;code&gt;, &lt;code&gt;fallback()&lt;&#x2F;code&gt; must be &lt;code&gt;external&lt;&#x2F;code&gt;. The &lt;code&gt;payable&lt;&#x2F;code&gt; modifier is optional. Without it, your fallback function will reject any Ether sent with the call.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-complete-example&quot;&gt;A Complete Example&lt;&#x2F;h2&gt;
&lt;p&gt;This contract implements both functions and logs which one was triggered:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;TestContract.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TestContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; func&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;fallback&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;receive&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And here is a contract to test it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Sender.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Sender&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendToReceive&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Empty data, so receive() runs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;        target.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendToFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Non-empty data, so fallback() runs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;        target.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;nonExistentFunc()&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When &lt;code&gt;sendToReceive&lt;&#x2F;code&gt; runs, &lt;code&gt;msg.data&lt;&#x2F;code&gt; is empty, so &lt;code&gt;receive()&lt;&#x2F;code&gt; executes. When &lt;code&gt;sendToFallback&lt;&#x2F;code&gt; runs, &lt;code&gt;msg.data&lt;&#x2F;code&gt; contains the encoded function signature, so &lt;code&gt;fallback()&lt;&#x2F;code&gt; executes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-happens-with-only-one-function&quot;&gt;What Happens With Only One Function&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;only-fallback-no-receive&quot;&gt;Only fallback(), no receive()&lt;&#x2F;h3&gt;
&lt;p&gt;If you define &lt;code&gt;fallback()&lt;&#x2F;code&gt; but not &lt;code&gt;receive()&lt;&#x2F;code&gt;, all incoming transactions route through &lt;code&gt;fallback()&lt;&#x2F;code&gt;. Plain Ether transfers and calls with data both end up there.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; OnlyFallback&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;all transactions come here&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This works, but you lose the ability to distinguish between plain transfers and unexpected function calls.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;only-receive-no-fallback&quot;&gt;Only receive(), no fallback()&lt;&#x2F;h3&gt;
&lt;p&gt;If you define &lt;code&gt;receive()&lt;&#x2F;code&gt; but not &lt;code&gt;fallback()&lt;&#x2F;code&gt;, calls to non-existent functions will revert. There is nothing to catch them.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; OnlyReceive&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;plain ether accepted&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Plain Ether transfers work fine. Any call with data causes a revert.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-real-wallet-example&quot;&gt;A Real Wallet Example&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a pattern you will see in practice. The contract accepts plain Ether but explicitly rejects calls to functions that do not exist:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Wallet.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Wallet&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FallbackTriggered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Deposit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; FallbackTriggered&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;Function does not exist&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using &lt;code&gt;revert&lt;&#x2F;code&gt; in &lt;code&gt;fallback()&lt;&#x2F;code&gt; is a common defensive pattern. If someone accidentally sends a transaction with the wrong function signature, the call fails cleanly instead of silently doing nothing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing-which-function-runs&quot;&gt;Testing Which Function Runs&lt;&#x2F;h2&gt;
&lt;p&gt;This contract lets you verify the routing yourself:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;FlowTest.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; FlowTest&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; receiveCount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; fallbackCount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        receiveCount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        fallbackCount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getBalance&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;).balance;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Tester&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; testReceive&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success,)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; target.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; testFallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable target&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success,)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; target.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;            abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSignature&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;random()&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Deploy &lt;code&gt;FlowTest&lt;&#x2F;code&gt;, then call &lt;code&gt;testReceive&lt;&#x2F;code&gt; and &lt;code&gt;testFallback&lt;&#x2F;code&gt; from &lt;code&gt;Tester&lt;&#x2F;code&gt;. Check &lt;code&gt;receiveCount&lt;&#x2F;code&gt; and &lt;code&gt;fallbackCount&lt;&#x2F;code&gt; to see exactly which function ran.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;key-rules&quot;&gt;Key Rules&lt;&#x2F;h2&gt;
&lt;p&gt;Both &lt;code&gt;receive()&lt;&#x2F;code&gt; and &lt;code&gt;fallback()&lt;&#x2F;code&gt; must be &lt;code&gt;external&lt;&#x2F;code&gt;. Using &lt;code&gt;public&lt;&#x2F;code&gt; will not compile:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Correct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Will not compile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To accept Ether, the function must be &lt;code&gt;payable&lt;&#x2F;code&gt;. Without it, any Ether sent with the transaction causes a revert:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Accepts Ether&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Rejects Ether&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Neither function takes parameters or returns values. Attempting this will not compile:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Will not compile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fallback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; x)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;If neither &lt;code&gt;receive()&lt;&#x2F;code&gt; nor &lt;code&gt;fallback()&lt;&#x2F;code&gt; is defined, your contract cannot accept Ether at all. Any transfer will revert. This is a common source of bugs when integrating with contracts that send Ether back to callers.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;receive()&lt;&#x2F;code&gt; handles plain Ether transfers with empty &lt;code&gt;msg.data&lt;&#x2F;code&gt;. &lt;code&gt;fallback()&lt;&#x2F;code&gt; handles everything else: unknown function calls and Ether transfers with data when no &lt;code&gt;receive()&lt;&#x2F;code&gt; exists. Having both gives you clean separation between the two cases. Having only one or the other has specific tradeoffs worth understanding before you deploy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sending Ether in Solidity: transfer, send, and call</title>
        <published>2025-11-05T00:00:00+00:00</published>
        <updated>2025-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/sending-ether-in-solidity-with-transfer-send-call/"/>
        <id>https://akash11.com/blog/sending-ether-in-solidity-with-transfer-send-call/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/sending-ether-in-solidity-with-transfer-send-call/">&lt;p&gt;Solidity gives you three ways to send Ether from a contract: &lt;code&gt;transfer&lt;&#x2F;code&gt;, &lt;code&gt;send&lt;&#x2F;code&gt;, and &lt;code&gt;call&lt;&#x2F;code&gt;. They look similar on the surface, but they behave very differently when it comes to gas, error handling, and security. Choosing the wrong one can break your contract or open it to attacks.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers how each method works, where they differ, and which one to use today.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-three-methods&quot;&gt;The Three Methods&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;transfer&quot;&gt;transfer&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;transfer&lt;&#x2F;code&gt; forwards a fixed &lt;strong&gt;2300 gas&lt;&#x2F;strong&gt; to the recipient and automatically reverts the entire transaction if the transfer fails. No return value. No manual error checking required.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendViaTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;    _to.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The 2300 gas stipend is intentionally small. It is enough for the recipient to emit an event, but not enough to make external calls or run complex logic. This was designed as a security feature to block reentrancy attacks.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;After the Istanbul hard fork (EIP-1884, 2019), the gas cost of &lt;code&gt;SLOAD&lt;&#x2F;code&gt; increased from 200 to 800. This means some recipient contracts that used to work fine with 2300 gas now run out of gas and cause &lt;code&gt;transfer&lt;&#x2F;code&gt; to fail. Contracts you did not write might break without any code change on your end.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;send&quot;&gt;send&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;send&lt;&#x2F;code&gt; also forwards 2300 gas, but instead of reverting on failure, it returns a &lt;code&gt;bool&lt;&#x2F;code&gt;. You are responsible for checking it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendViaSend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; sent &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _to.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(sent,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Failed to send Ether&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you forget to check the return value, your contract continues executing as if the transfer succeeded, even when it did not. This is a real bug pattern. The Solidity compiler will warn you, but it will not stop you.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;send&lt;&#x2F;code&gt; has the same gas-related problems as &lt;code&gt;transfer&lt;&#x2F;code&gt;. There is almost no reason to use it over &lt;code&gt;transfer&lt;&#x2F;code&gt; (if you want automatic revert) or &lt;code&gt;call&lt;&#x2F;code&gt; (if you want flexibility).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;call&quot;&gt;call&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;call&lt;&#x2F;code&gt; is a low-level function. It forwards all remaining gas by default and returns two values: a success boolean and any returned bytes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendViaCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; sent,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; data)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _to.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(sent,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Failed to send Ether&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;{value: msg.value}&lt;&#x2F;code&gt; syntax sets how much Ether to send. The empty string &lt;code&gt;&quot;&quot;&lt;&#x2F;code&gt; means you are not calling a specific function on the recipient, just sending Ether.&lt;&#x2F;p&gt;
&lt;p&gt;You can also specify a custom gas limit:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; sent, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _to.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value, gas:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10000&lt;&#x2F;span&gt;&lt;span&gt;}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because &lt;code&gt;call&lt;&#x2F;code&gt; forwards all gas, the recipient can run complex logic. This makes it flexible, but it also means reentrancy attacks become possible if you are not careful.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;comparison-at-a-glance&quot;&gt;Comparison at a Glance&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Method&lt;&#x2F;th&gt;&lt;th&gt;Gas forwarded&lt;&#x2F;th&gt;&lt;th&gt;On failure&lt;&#x2F;th&gt;&lt;th&gt;Manual check needed&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;transfer&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2300 (fixed)&lt;&#x2F;td&gt;&lt;td&gt;Reverts automatically&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;send&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2300 (fixed)&lt;&#x2F;td&gt;&lt;td&gt;Returns &lt;code&gt;false&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;call&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;All remaining (configurable)&lt;&#x2F;td&gt;&lt;td&gt;Returns &lt;code&gt;false&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;which-method-to-use&quot;&gt;Which Method to Use&lt;&#x2F;h2&gt;
&lt;p&gt;Use &lt;code&gt;call&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;After EIP-1884, the 2300 gas limit is no longer a reliable safety net. &lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;send&lt;&#x2F;code&gt; can silently break when interacting with contracts that have non-trivial fallback logic. &lt;code&gt;call&lt;&#x2F;code&gt; avoids this by not capping gas, and it gives you full control over error handling.&lt;&#x2F;p&gt;
&lt;p&gt;The tradeoff is that &lt;code&gt;call&lt;&#x2F;code&gt; requires you to handle reentrancy yourself. The standard approach is the &lt;strong&gt;checks-effects-interactions&lt;&#x2F;strong&gt; pattern: update all state before making any external call.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;SafeSender.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SafeSender&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint&lt;&#x2F;span&gt;&lt;span&gt; amount &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(amount &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Nothing to withdraw&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Effect: update state before external call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Interaction: send Ether last&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;.call{value: amount}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Transfer failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The balance is set to zero before calling &lt;code&gt;call&lt;&#x2F;code&gt;. Even if the recipient re-enters &lt;code&gt;withdraw&lt;&#x2F;code&gt;, their balance is already zero, so they get nothing on the second call.&lt;&#x2F;p&gt;
&lt;p&gt;If your withdrawal logic is more complex, consider a reentrancy guard instead of relying solely on ordering:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;ReentrancyGuard.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SafeSenderWithGuard&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; locked;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; noReentrant&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(!locked,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;No reentrancy&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        locked &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        _&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;        locked &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; noReentrant&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint&lt;&#x2F;span&gt;&lt;span&gt; amount &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(amount &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Nothing to withdraw&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;.call{value: amount}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Transfer failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;receiving-ether-in-a-contract&quot;&gt;Receiving Ether in a Contract&lt;&#x2F;h2&gt;
&lt;p&gt;For a contract to receive Ether sent via &lt;code&gt;call&lt;&#x2F;code&gt;, it needs at least one of these functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; EtherReceiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Called when msg.data is empty (plain Ether transfer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Called when no other function matches&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    fallback&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;receive&lt;&#x2F;code&gt; handles plain Ether transfers with no calldata. &lt;code&gt;fallback&lt;&#x2F;code&gt; catches everything else. If neither exists, the contract will reject incoming Ether and cause your &lt;code&gt;call&lt;&#x2F;code&gt; to fail.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;full-working-example&quot;&gt;Full Working Example&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;EtherSender.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; EtherSender&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendViaTransfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        _to.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendViaSend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        bool&lt;&#x2F;span&gt;&lt;span&gt; sent &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _to.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(sent,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Send failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sendViaCall&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; payable&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _to&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; sent, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; _to.call{value:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(sent,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Call failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; EtherReceiver&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; sender&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    receive&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Received&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When you call &lt;code&gt;sendViaCall&lt;&#x2F;code&gt; with 1 Ether and pass an &lt;code&gt;EtherReceiver&lt;&#x2F;code&gt; address, the Ether is forwarded and the &lt;code&gt;Received&lt;&#x2F;code&gt; event is emitted. The other two methods will also work with this receiver, but they carry the gas-limit risk described above.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Use &lt;code&gt;call&lt;&#x2F;code&gt; for sending Ether in any contract you write today. Always check the boolean return value. Always update contract state before the external call.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;transfer&lt;&#x2F;code&gt; and &lt;code&gt;send&lt;&#x2F;code&gt; exist in older contracts and tutorials, so you will see them. But the gas assumptions they rely on are no longer safe after Istanbul. &lt;code&gt;call&lt;&#x2F;code&gt; with the checks-effects-interactions pattern (or a reentrancy guard) is the right approach.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Inheritance in Solidity</title>
        <published>2025-11-04T00:00:00+00:00</published>
        <updated>2025-11-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/inheritance-in-solidity/"/>
        <id>https://akash11.com/blog/inheritance-in-solidity/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/inheritance-in-solidity/">&lt;p&gt;Solidity lets contracts inherit from other contracts. The child contract gets all the public and internal functions and state variables of the parent. This lets you split logic across multiple focused contracts and reuse it across your codebase without copying code.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers the four core mechanisms: &lt;code&gt;is&lt;&#x2F;code&gt;, &lt;code&gt;virtual&lt;&#x2F;code&gt;, &lt;code&gt;override&lt;&#x2F;code&gt;, and &lt;code&gt;super&lt;&#x2F;code&gt;. It also covers multiple inheritance, how Solidity resolves conflicts between parents, and a few mistakes worth knowing about before they bite you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-is-keyword&quot;&gt;The &lt;code&gt;is&lt;&#x2F;code&gt; Keyword&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;is&lt;&#x2F;code&gt; establishes the inheritance relationship. Write &lt;code&gt;contract Child is Parent&lt;&#x2F;code&gt; and the child contract inherits everything that is not private.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;direct-inheritance.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Animal&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; makeSound&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Some sound&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Dog&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Animal&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; makeSound&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure override returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Woof!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;Dog&lt;&#x2F;code&gt; gets &lt;code&gt;name&lt;&#x2F;code&gt; from &lt;code&gt;Animal&lt;&#x2F;code&gt; for free. It replaces &lt;code&gt;makeSound&lt;&#x2F;code&gt; with its own version.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;virtual-and-override&quot;&gt;&lt;code&gt;virtual&lt;&#x2F;code&gt; and &lt;code&gt;override&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;These two keywords always work together.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;virtual&lt;&#x2F;code&gt; marks a function in the parent as replaceable. Without it, child contracts cannot override the function. Solidity will throw a compiler error if they try.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;override&lt;&#x2F;code&gt; marks a function in the child as a replacement for a parent&#x27;s &lt;code&gt;virtual&lt;&#x2F;code&gt; function. Without it, the compiler will also error. This is intentional. Both sides must opt in.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;virtual-override.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Base&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Child contracts can replace this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; calculate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Child contracts cannot replace this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; fixedFunction&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Derived&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Base&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; calculate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure override returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 99&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you write a function in the child that matches a parent function&#x27;s name but forget &lt;code&gt;override&lt;&#x2F;code&gt;, Solidity errors. This prevents accidental shadowing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-super-keyword&quot;&gt;The &lt;code&gt;super&lt;&#x2F;code&gt; Keyword&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;super&lt;&#x2F;code&gt; calls the function from the parent contract. Use it when you want to extend the parent&#x27;s behavior rather than fully replace it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;super.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Counter&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; count;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; increment&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public virtual&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        count &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; DoubleCounter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Counter&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; increment&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public override&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;increment&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; runs parent logic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;increment&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; runs it again&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Without &lt;code&gt;super&lt;&#x2F;code&gt;, calling &lt;code&gt;increment()&lt;&#x2F;code&gt; in the child would only run the child&#x27;s logic. The parent&#x27;s logic would be skipped entirely.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiple-inheritance&quot;&gt;Multiple Inheritance&lt;&#x2F;h2&gt;
&lt;p&gt;A contract can inherit from more than one parent.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;multiple-parents.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;A&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; B&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; bar&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;B&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; C&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getValues&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; bar&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;C&lt;&#x2F;code&gt; has access to both &lt;code&gt;foo&lt;&#x2F;code&gt; from &lt;code&gt;A&lt;&#x2F;code&gt; and &lt;code&gt;bar&lt;&#x2F;code&gt; from &lt;code&gt;B&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The situation gets more complex when two parents define the same function name.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;conflict.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; X&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getValue&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Y&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getValue&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Z&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; X&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Y&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Must override explicitly, listing both parents&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getValue&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;X&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Y&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When a function exists in multiple parents, you must list all of them inside &lt;code&gt;override(...)&lt;&#x2F;code&gt;. If you do not override at all, the compiler refuses to compile because it cannot decide which parent&#x27;s version to use.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inheritance-order-and-c3-linearization&quot;&gt;Inheritance Order and C3 Linearization&lt;&#x2F;h2&gt;
&lt;p&gt;Solidity resolves multiple inheritance using C3 linearization. The practical rule: list parent contracts from most general to most specific, left to right. Solidity processes them right to left internally.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;linearization.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Base1&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; greet&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Hello from Base1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Base2&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; greet&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure virtual returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Hello from Base2&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Derived&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Base1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Base2&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; greet&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;Base1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Base2&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Hello from Derived&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This matters most when using &lt;code&gt;super&lt;&#x2F;code&gt; in a chain of contracts. Solidity will walk the chain in linearized order.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;super-chain.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; message&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; process&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public virtual&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;A processed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; B&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; process&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public virtual override&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;B processed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;process&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; C&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; A&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; process&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public virtual override&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;C processed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;process&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; D&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; B&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; process&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public override&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;B&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; C&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;process&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When &lt;code&gt;D&lt;&#x2F;code&gt; calls &lt;code&gt;super.process()&lt;&#x2F;code&gt;, the linearized order is &lt;code&gt;D, C, B, A&lt;&#x2F;code&gt;. So &lt;code&gt;C.process()&lt;&#x2F;code&gt; runs first, then &lt;code&gt;B.process()&lt;&#x2F;code&gt;, then &lt;code&gt;A.process()&lt;&#x2F;code&gt;. Each call to &lt;code&gt;super&lt;&#x2F;code&gt; passes control to the next in that chain.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
&lt;p&gt;The linearization order is deterministic and computed at compile time. Solidity will reject inheritance hierarchies that cannot be linearized cleanly.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;a-practical-example&quot;&gt;A Practical Example&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a pattern you will see often in real contracts: a &lt;code&gt;Token&lt;&#x2F;code&gt; that is both ownable and pausable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;token.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Ownable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    modifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; == owner,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;        _&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transferOwnership&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newOwner&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public virtual&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newOwner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Pausable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; paused;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; pause&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public virtual&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;        paused &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; unpause&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public virtual&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;        paused &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Ownable&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;Pausable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(!paused,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Contract is paused&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;        balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;41&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Override to restrict to owner only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; pause&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public override&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;44&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;pause&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;46&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; unpause&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public override&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; onlyOwner&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;48&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;font-style: italic;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;unpause&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;49&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;Token&lt;&#x2F;code&gt; inherits &lt;code&gt;owner&lt;&#x2F;code&gt;, &lt;code&gt;onlyOwner&lt;&#x2F;code&gt;, and &lt;code&gt;transferOwnership&lt;&#x2F;code&gt; from &lt;code&gt;Ownable&lt;&#x2F;code&gt;. It inherits &lt;code&gt;paused&lt;&#x2F;code&gt;, &lt;code&gt;pause&lt;&#x2F;code&gt;, and &lt;code&gt;unpause&lt;&#x2F;code&gt; from &lt;code&gt;Pausable&lt;&#x2F;code&gt;. It then narrows the pause functions with the &lt;code&gt;onlyOwner&lt;&#x2F;code&gt; modifier, and uses &lt;code&gt;super&lt;&#x2F;code&gt; to call the original implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;common-mistakes&quot;&gt;Common Mistakes&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;State variable shadowing.&lt;&#x2F;strong&gt; You cannot declare a state variable in a child with the same name as one in a parent. The compiler will error.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;shadowing.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Parent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Child&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Parent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Compiler error: cannot shadow parent&amp;#39;s state variable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; uint public value = 20;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Constructor arguments.&lt;&#x2F;strong&gt; Parent constructors run before child constructors. If a parent requires constructor arguments, you must pass them in the child.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;constructor.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Parent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt; _value&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        value &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; _value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Pass the argument directly in the inheritance list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Child&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Parent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; runs after Parent constructor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Visibility.&lt;&#x2F;strong&gt; You can only override &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt; functions. &lt;code&gt;private&lt;&#x2F;code&gt; functions are not visible to child contracts at all. &lt;code&gt;internal&lt;&#x2F;code&gt; functions are visible and can be called, but they cannot be marked &lt;code&gt;virtual&lt;&#x2F;code&gt; and overridden unless the parent explicitly allows it.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Inheritance in Solidity gives you a clean way to separate concerns across contracts and reuse logic without duplication. The four keywords (&lt;code&gt;is&lt;&#x2F;code&gt;, &lt;code&gt;virtual&lt;&#x2F;code&gt;, &lt;code&gt;override&lt;&#x2F;code&gt;, &lt;code&gt;super&lt;&#x2F;code&gt;) each serve a distinct role, and understanding how they interact with multiple inheritance and linearization will save you from confusing compiler errors when contracts get more complex.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Visibility in Solidity</title>
        <published>2025-11-04T00:00:00+00:00</published>
        <updated>2025-11-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/visibility-in-solidity/"/>
        <id>https://akash11.com/blog/visibility-in-solidity/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/visibility-in-solidity/">&lt;p&gt;Solidity gives you four visibility modifiers: &lt;code&gt;public&lt;&#x2F;code&gt;, &lt;code&gt;private&lt;&#x2F;code&gt;, &lt;code&gt;internal&lt;&#x2F;code&gt;, and &lt;code&gt;external&lt;&#x2F;code&gt;. They control which code can call a function or read a state variable. Getting them wrong either locks down functionality that should be open, or exposes internals that should stay hidden.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains what each modifier does, where it applies, how it interacts with inheritance, and when to reach for each one.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;the-four-modifiers-at-a-glance&quot;&gt;The Four Modifiers at a Glance&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Modifier&lt;&#x2F;th&gt;&lt;th&gt;State variables&lt;&#x2F;th&gt;&lt;th&gt;Functions&lt;&#x2F;th&gt;&lt;th&gt;Who can access&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;public&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Anyone, anywhere&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;private&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Current contract only&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;internal&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Yes (default)&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Current contract and derived contracts&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;external&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Outside callers only&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;code&gt;external&lt;&#x2F;code&gt; cannot be used on state variables. Attempting it will cause a compile error.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;state-variable-visibility&quot;&gt;State Variable Visibility&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;public&quot;&gt;public&lt;&#x2F;h3&gt;
&lt;p&gt;Declaring a state variable &lt;code&gt;public&lt;&#x2F;code&gt; tells the compiler to generate a getter function automatically. External callers use that getter to read the value. You do not write it yourself.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; VisibilityExample&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; myNumber &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Compiler generates: function myNumber() public view returns (uint256)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Any external contract or wallet can call &lt;code&gt;myNumber()&lt;&#x2F;code&gt; and get back &lt;code&gt;42&lt;&#x2F;code&gt;. This is clean and convenient, but only declare variables &lt;code&gt;public&lt;&#x2F;code&gt; if you actually want them readable by anyone.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;private&quot;&gt;private&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;private&lt;&#x2F;code&gt; variable can only be accessed by functions inside the same contract. Derived contracts cannot read it, even though they inherit from the same base.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; MyContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; secretValue &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; revealSecret&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; secretValue;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; allowed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ChildContract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; MyContract&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; tryAccess&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; return secretValue; &#x2F;&#x2F; compile error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;&lt;code&gt;private&lt;&#x2F;code&gt; does not hide data from the blockchain. All storage slots are publicly readable by anyone who queries the chain directly. &lt;code&gt;private&lt;&#x2F;code&gt; only prevents other Solidity contracts from referencing the variable by name. Never store sensitive data on-chain and assume &lt;code&gt;private&lt;&#x2F;code&gt; protects it.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;internal&quot;&gt;internal&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;internal&lt;&#x2F;code&gt; is the default visibility for state variables. If you declare a variable without specifying visibility, Solidity treats it as &lt;code&gt;internal&lt;&#x2F;code&gt;. The variable is accessible within the contract and within any contract that inherits from it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Parent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; familySecret &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 500&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Child&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Parent&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; read&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; familySecret;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; allowed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Prefer writing &lt;code&gt;internal&lt;&#x2F;code&gt; explicitly rather than relying on the default. It makes intent clear.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;function-visibility&quot;&gt;Function Visibility&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;public-1&quot;&gt;public&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;public&lt;&#x2F;code&gt; function can be called from inside the contract or from outside. It is the most flexible option, but it has a cost: when called internally, Solidity copies function arguments into memory. For small inputs this does not matter, but for large arrays it adds unnecessary gas overhead.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Calculator&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; calculate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; internal call to public function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;external&quot;&gt;external&lt;&#x2F;h3&gt;
&lt;p&gt;An &lt;code&gt;external&lt;&#x2F;code&gt; function can only be called from outside the contract. You cannot call it directly by name from within the same contract. Calling it internally requires &lt;code&gt;this.functionName()&lt;&#x2F;code&gt;, which creates an external call and costs significantly more gas.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; DataProcessor&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processData&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; data.length;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; internalProcess&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; testData &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; return processData(testData); &#x2F;&#x2F; compile error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;processData&lt;&#x2F;span&gt;&lt;span&gt;(testData);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; works, but expensive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The main advantage of &lt;code&gt;external&lt;&#x2F;code&gt; is that it allows &lt;code&gt;calldata&lt;&#x2F;code&gt; for array parameters. &lt;code&gt;calldata&lt;&#x2F;code&gt; is read directly from the transaction input without copying, which is cheaper than loading into memory. If a function only ever gets called from outside and accepts large arrays, &lt;code&gt;external&lt;&#x2F;code&gt; with &lt;code&gt;calldata&lt;&#x2F;code&gt; is the correct choice.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;internal-1&quot;&gt;internal&lt;&#x2F;h3&gt;
&lt;p&gt;An &lt;code&gt;internal&lt;&#x2F;code&gt; function is accessible within the contract and in any contract that inherits from it. It is never part of the contract&#x27;s ABI, so no external caller can invoke it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Math&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; multiply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; square&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; multiply&lt;&#x2F;span&gt;&lt;span&gt;(x, x);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; AdvancedMath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Math&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; cube&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; multiply&lt;&#x2F;span&gt;&lt;span&gt;(x,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; multiply&lt;&#x2F;span&gt;&lt;span&gt;(x, x));&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; inherited, accessible&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Use &lt;code&gt;internal&lt;&#x2F;code&gt; for helper functions that child contracts may need to reuse. It avoids duplicating logic while keeping the function off the public interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;private-1&quot;&gt;private&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;code&gt;private&lt;&#x2F;code&gt; function works the same as &lt;code&gt;internal&lt;&#x2F;code&gt; within the current contract, but derived contracts cannot call it at all.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Secure&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; counter;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; incrementCounter&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        counter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; doSomething&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        incrementCounter&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; allowed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Extended&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Secure&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; tryIncrement&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; incrementCounter(); &#x2F;&#x2F; compile error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Use &lt;code&gt;private&lt;&#x2F;code&gt; when a function is a low-level implementation detail that should never be part of an inheritance interface.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;visibility-across-inheritance&quot;&gt;Visibility Across Inheritance&lt;&#x2F;h2&gt;
&lt;p&gt;This example shows all four modifiers in one inheritance scenario:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Base&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; publicVar &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; internalVar &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; privateVar &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; publicFunc&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;public&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; internalFunc&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;internal&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; privateFunc&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;private&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Derived&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Base&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; testAccess&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; sum &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; publicVar &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; internalVar;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; both accessible&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; uint256 bad = privateVar;           &#x2F;&#x2F; compile error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        publicFunc&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; accessible&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        internalFunc&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; accessible&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; privateFunc(); &#x2F;&#x2F; compile error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; sum;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Derived contracts inherit &lt;code&gt;public&lt;&#x2F;code&gt; and &lt;code&gt;internal&lt;&#x2F;code&gt; members. They never get access to &lt;code&gt;private&lt;&#x2F;code&gt; members. This is a hard boundary enforced at compile time.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;practical-guidelines&quot;&gt;Practical Guidelines&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Default to the most restrictive option.&lt;&#x2F;strong&gt; Start with &lt;code&gt;private&lt;&#x2F;code&gt;. Move to &lt;code&gt;internal&lt;&#x2F;code&gt; if child contracts need access. Move to &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt; only if outside callers need it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Use &lt;code&gt;external&lt;&#x2F;code&gt; for functions that only serve outside callers.&lt;&#x2F;strong&gt; Especially if those functions accept array parameters. The &lt;code&gt;calldata&lt;&#x2F;code&gt; keyword saves gas and &lt;code&gt;external&lt;&#x2F;code&gt; makes the intent explicit.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Use &lt;code&gt;internal&lt;&#x2F;code&gt; for shared helpers in a contract family.&lt;&#x2F;strong&gt; It is cleaner than duplicating logic or making everything &lt;code&gt;public&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Do not treat &lt;code&gt;private&lt;&#x2F;code&gt; as encryption.&lt;&#x2F;strong&gt; All on-chain state is readable. Use &lt;code&gt;private&lt;&#x2F;code&gt; for access control at the Solidity level, not for data confidentiality.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Let the compiler generate getters.&lt;&#x2F;strong&gt; Public state variables get their getter for free. Only write a custom getter if you need to transform or filter the output.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;common-mistakes&quot;&gt;Common Mistakes&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;mistakes.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Mistakes&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Mistake 1: public when internal would work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Nothing outside this contract reads helperValue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; helperValue;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Mistake 2: public when external would work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; This function is never called internally&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Switching to external with calldata saves gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; data.length;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Mistake 3: missing visibility on a function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Default for functions is internal, not public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; This function is not callable externally&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; oops&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The third mistake is subtle. State variables default to &lt;code&gt;internal&lt;&#x2F;code&gt;, but functions also default to &lt;code&gt;internal&lt;&#x2F;code&gt; if you omit the modifier. A function without visibility is invisible to external callers, which may not be what you intended. Always write visibility explicitly on functions.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;visibility-and-attack-surface&quot;&gt;Visibility and Attack Surface&lt;&#x2F;h2&gt;
&lt;p&gt;Every &lt;code&gt;public&lt;&#x2F;code&gt; or &lt;code&gt;external&lt;&#x2F;code&gt; function is an entry point into your contract. Unnecessary exposure increases the number of ways an attacker can interact with your code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;secure.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; SecureExample&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deposit&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Private: only used internally, not part of the ABI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; updateBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        balances[user]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; External: read-only, only exposes the caller&amp;#39;s own balance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getBalance&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;balances&lt;&#x2F;code&gt; mapping is &lt;code&gt;private&lt;&#x2F;code&gt;. The &lt;code&gt;updateBalance&lt;&#x2F;code&gt; helper is &lt;code&gt;private&lt;&#x2F;code&gt;. The only entry points are &lt;code&gt;deposit&lt;&#x2F;code&gt; and &lt;code&gt;getBalance&lt;&#x2F;code&gt;. This is the smallest possible attack surface for this functionality.&lt;&#x2F;p&gt;
&lt;p&gt;Keeping functions &lt;code&gt;private&lt;&#x2F;code&gt; or &lt;code&gt;internal&lt;&#x2F;code&gt; until you have a reason to expose them is a habit that pays off in audit findings and in production.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Visibility modifiers are straightforward once you understand what each one controls. The rule is simple: expose only what needs to be exposed, and be explicit about every choice. A contract where every variable and function has a deliberate visibility modifier is easier to audit, easier to extend, and harder to exploit.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Data Locations in Solidity: storage, memory, and calldata</title>
        <published>2025-11-03T00:00:00+00:00</published>
        <updated>2025-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/solidity-data-locations-storage-memory-calldata/"/>
        <id>https://akash11.com/blog/solidity-data-locations-storage-memory-calldata/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/solidity-data-locations-storage-memory-calldata/">&lt;p&gt;Every variable in Solidity lives somewhere. That somewhere is called a data location, and Solidity gives you three: &lt;code&gt;storage&lt;&#x2F;code&gt;, &lt;code&gt;memory&lt;&#x2F;code&gt;, and &lt;code&gt;calldata&lt;&#x2F;code&gt;. Getting this right matters. The wrong location can silently break your contract by updating a copy instead of the real state, or waste gas on unnecessary data copying.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers how each location works, when to use each one, and the specific rules that apply to state variables, function parameters, local variables, and return values.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;the-three-locations&quot;&gt;The Three Locations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;storage&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; is persistent. It lives on the blockchain and survives between function calls. Every state variable in your contract lives in storage.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;memory&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; is temporary. It exists only while a function is executing. Once the function returns, memory is gone.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;calldata&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; is read-only. When someone calls an external function, the arguments arrive in calldata. You cannot modify calldata. You can only read from it.&lt;&#x2F;p&gt;
&lt;p&gt;The location you choose affects three things: gas cost, whether you can modify the data, and how long the data exists.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;state-variables&quot;&gt;State Variables&lt;&#x2F;h2&gt;
&lt;p&gt;State variables are declared at the contract level, outside of any function. They always live in &lt;code&gt;storage&lt;&#x2F;code&gt;. You never add a location keyword to a state variable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TokenRegistry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; totalSupply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; allIds;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; id;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    Token[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; tokens;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Adding a location keyword to a state variable is a compile error:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; This will not compile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; counter;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;State variables are &lt;code&gt;storage&lt;&#x2F;code&gt; by definition. The keyword is not allowed and not needed.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;value-types-vs-reference-types&quot;&gt;Value Types vs Reference Types&lt;&#x2F;h2&gt;
&lt;p&gt;Before looking at function variables and parameters, you need to understand one distinction: value types vs reference types.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Value types&lt;&#x2F;strong&gt; include &lt;code&gt;uint&lt;&#x2F;code&gt;, &lt;code&gt;int&lt;&#x2F;code&gt;, &lt;code&gt;bool&lt;&#x2F;code&gt;, &lt;code&gt;address&lt;&#x2F;code&gt;, &lt;code&gt;bytes1&lt;&#x2F;code&gt; through &lt;code&gt;bytes32&lt;&#x2F;code&gt;, and enums. When you assign a value type, Solidity copies it. There is no &quot;reference&quot; to the original. Because of this, value types never need a location keyword.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Reference types&lt;&#x2F;strong&gt; include arrays, structs, strings, and &lt;code&gt;bytes&lt;&#x2F;code&gt;. When you assign a reference type, it can either point to the original or be a new copy, depending on the location you specify. This is where the choice matters.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;local-variables-inside-functions&quot;&gt;Local Variables Inside Functions&lt;&#x2F;h2&gt;
&lt;p&gt;When you declare a local variable of a reference type inside a function, you must choose &lt;code&gt;storage&lt;&#x2F;code&gt; or &lt;code&gt;memory&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;storage-gives-you-a-reference&quot;&gt;storage gives you a reference&lt;&#x2F;h3&gt;
&lt;p&gt;Using &lt;code&gt;storage&lt;&#x2F;code&gt; creates a pointer to a state variable. Changes through that pointer modify the actual state.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Example&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; addToState&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; storageRef points to the state variable &amp;#39;numbers&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span&gt; storageRef &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        storageRef.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; This modifies &amp;#39;numbers&amp;#39; in state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;memory-gives-you-a-copy&quot;&gt;memory gives you a copy&lt;&#x2F;h3&gt;
&lt;p&gt;Using &lt;code&gt;memory&lt;&#x2F;code&gt; creates a temporary copy of the data. Changes to it do not touch the state variable.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Example&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; readOnly&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; memoryCopy is a separate copy, changes here go nowhere&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; memoryCopy &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        memoryCopy[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 999&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Only modifies the local copy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The same rule applies to structs:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Example&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Person&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; age;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    Person &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;public&lt;&#x2F;span&gt;&lt;span&gt; person;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; updateAge&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Wrong: creates a copy, state is unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        Person &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;memory&lt;&#x2F;span&gt;&lt;span&gt; copy &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; person;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        copy.age &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Correct: storage reference, state is updated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        Person &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; ref &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; person;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;        ref.age &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Using &lt;code&gt;memory&lt;&#x2F;code&gt; when you meant &lt;code&gt;storage&lt;&#x2F;code&gt; is a silent bug. The compiler will not warn you. The function will run, the copy will be modified, and the state variable will remain unchanged. Always double-check which one you need before writing a local reference type variable.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;creating-new-data-in-memory&quot;&gt;Creating new data in memory&lt;&#x2F;h3&gt;
&lt;p&gt;When you create a new array or struct inside a function, it always goes in &lt;code&gt;memory&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; buildArray&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;    result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;    result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;    result[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; result;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Value types in local variables need no location keyword:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; calculate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; total &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; No keyword needed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; found &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; No keyword needed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; sender &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; No keyword needed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; total;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;function-parameters&quot;&gt;Function Parameters&lt;&#x2F;h2&gt;
&lt;p&gt;The right location for a function parameter depends on the function visibility and whether you need to modify the data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;external-functions-use-calldata&quot;&gt;External functions: use calldata&lt;&#x2F;h3&gt;
&lt;p&gt;External functions can only be called from outside the contract. For reference type parameters, &lt;code&gt;calldata&lt;&#x2F;code&gt; is the most efficient choice. The data arrives in calldata already, so using &lt;code&gt;calldata&lt;&#x2F;code&gt; means no copying.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TokenRegistry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; id;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; registerTokens&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Token&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newTokens&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; newTokens.length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; Reading from calldata is cheap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; Cannot modify newTokens[i] directly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getNameLength&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bytes&lt;&#x2F;span&gt;&lt;span&gt;(name).length;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Because &lt;code&gt;calldata&lt;&#x2F;code&gt; is read-only, you cannot modify the parameter. If you need to modify the data inside the function, copy it to memory first.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;public-functions-calldata-or-memory&quot;&gt;Public functions: calldata or memory&lt;&#x2F;h3&gt;
&lt;p&gt;Public functions can be called externally or from within the contract. Both &lt;code&gt;calldata&lt;&#x2F;code&gt; and &lt;code&gt;memory&lt;&#x2F;code&gt; are valid for reference type parameters.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;calldata&lt;&#x2F;code&gt; costs less gas when called externally. &lt;code&gt;memory&lt;&#x2F;code&gt; is required when the function is called internally, since internal calls cannot pass calldata directly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Example&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Works, but costs more gas when called externally&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withMemory&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; data.length;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; More efficient for external callers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withCalldata&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; data.length;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For &lt;code&gt;public&lt;&#x2F;code&gt; functions that are called mostly externally, prefer &lt;code&gt;calldata&lt;&#x2F;code&gt;. For functions that are also called internally, &lt;code&gt;memory&lt;&#x2F;code&gt; is the safer default.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;internal-and-private-functions-memory-or-storage&quot;&gt;Internal and private functions: memory or storage&lt;&#x2F;h3&gt;
&lt;p&gt;Internal and private functions cannot be called from outside the contract. You can pass either a &lt;code&gt;memory&lt;&#x2F;code&gt; copy or a &lt;code&gt;storage&lt;&#x2F;code&gt; reference.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Example&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Internal function that modifies state via storage reference&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; addToArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; arr&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        arr.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Internal function that reads from a memory array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sumArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; arr&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; total &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; arr.length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;            total &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span&gt; arr[i];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; total;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; run&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        addToArray&lt;&#x2F;span&gt;&lt;span&gt;(numbers,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Passes storage reference&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; temp &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;        temp[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;        temp[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;        temp[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sumArray&lt;&#x2F;span&gt;&lt;span&gt;(temp);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Passes memory array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Value type parameters never take a location keyword, regardless of function visibility:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Correct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; verified&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Compile error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; function transfer(uint256 memory amount) public { }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;return-values&quot;&gt;Return Values&lt;&#x2F;h2&gt;
&lt;p&gt;Value types returned from functions need no location keyword. Reference types must use &lt;code&gt;memory&lt;&#x2F;code&gt; or &lt;code&gt;calldata&lt;&#x2F;code&gt;. You cannot return a &lt;code&gt;storage&lt;&#x2F;code&gt; reference.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;returning-reference-types-from-state&quot;&gt;Returning reference types from state&lt;&#x2F;h3&gt;
&lt;p&gt;When a function returns an array or struct from state, Solidity copies it into memory first:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Example&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; text;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getNumbers&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Copied from storage to memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getText&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; text;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;returning-newly-created-data&quot;&gt;Returning newly created data&lt;&#x2F;h3&gt;
&lt;p&gt;When you create data inside a function and return it, it must be &lt;code&gt;memory&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; buildRange&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; n&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; n; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;        result[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; i;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; result;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;returning-calldata-directly&quot;&gt;Returning calldata directly&lt;&#x2F;h3&gt;
&lt;p&gt;If a function receives a &lt;code&gt;calldata&lt;&#x2F;code&gt; parameter and you want to return it unchanged, you can return &lt;code&gt;calldata&lt;&#x2F;code&gt; directly. This avoids copying and saves gas:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; passThrough&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; input;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; No copy, very efficient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This only works when you return the same calldata without modification.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;a-full-example&quot;&gt;A Full Example&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a contract that uses all three locations together, showing how they interact:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;TokenRegistry.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TokenRegistry&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; State variables: always storage, no keyword&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; totalCount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; id;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        address&lt;&#x2F;span&gt;&lt;span&gt; tokenOwner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;    Token[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; tokens;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; ownerTokenIds;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; value type, no keyword&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;        totalCount &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; External: calldata for reference types&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; batchRegister&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Token&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newTokens&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; external&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; == owner,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Not owner&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; newTokens.length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span&gt;            tokens.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(newTokens[i]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;            ownerTokenIds[newTokens[i].tokenOwner].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(newTokens[i].id);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;            totalCount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Public: returns memory copy from state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;Token memory&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; tokens[index];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;37&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Internal: storage reference to modify state directly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; updateName&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; index&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newName&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;        Token &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;storage&lt;&#x2F;span&gt;&lt;span&gt; token &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; tokens[index];&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; storage reference&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;        token.name &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newName;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;               &#x2F;&#x2F; modifies state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;43&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;44&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Internal: pure calculation using memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sumIds&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; ids&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; internal pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; total &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; ids.length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;48&lt;&#x2F;span&gt;&lt;span&gt;            total &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span&gt; ids[i];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;49&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; total;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;51&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;52&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;53&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Public: mixes calldata input with storage and memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;54&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processAndUpdate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;55&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; calldata&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; inputIds&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;56&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; updateIndex&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;57&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newName&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;58&lt;&#x2F;span&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;59&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Work with storage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;60&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; storage&lt;&#x2F;span&gt;&lt;span&gt; ownerIds &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; ownerTokenIds[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;61&lt;&#x2F;span&gt;&lt;span&gt;        ownerIds.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(inputIds[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; modifies state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;62&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;63&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Work with memory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; memory&lt;&#x2F;span&gt;&lt;span&gt; tempIds &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;[](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;inputIds&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;65&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; inputIds.length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;66&lt;&#x2F;span&gt;&lt;span&gt;            tempIds[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; inputIds[i];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;67&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;68&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;        updateName&lt;&#x2F;span&gt;&lt;span&gt;(updateIndex, newName);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; passes memory string to internal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;70&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;71&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; sumIds&lt;&#x2F;span&gt;&lt;span&gt;(tempIds);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; passes memory array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;72&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;73&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;quick-reference&quot;&gt;Quick Reference&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Context&lt;&#x2F;th&gt;&lt;th&gt;Value types&lt;&#x2F;th&gt;&lt;th&gt;Reference types&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;State variables&lt;&#x2F;td&gt;&lt;td&gt;No keyword (always &lt;code&gt;storage&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;td&gt;No keyword (always &lt;code&gt;storage&lt;&#x2F;code&gt;)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Local variable pointing to state&lt;&#x2F;td&gt;&lt;td&gt;No keyword&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;storage&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Local variable for temporary use&lt;&#x2F;td&gt;&lt;td&gt;No keyword&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;memory&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;External function parameter&lt;&#x2F;td&gt;&lt;td&gt;No keyword&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;calldata&lt;&#x2F;code&gt; (preferred)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Public function parameter&lt;&#x2F;td&gt;&lt;td&gt;No keyword&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;calldata&lt;&#x2F;code&gt; or &lt;code&gt;memory&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Internal&#x2F;private function parameter&lt;&#x2F;td&gt;&lt;td&gt;No keyword&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;memory&lt;&#x2F;code&gt; or &lt;code&gt;storage&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Return value&lt;&#x2F;td&gt;&lt;td&gt;No keyword&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;memory&lt;&#x2F;code&gt; or &lt;code&gt;calldata&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The pattern is consistent once you see it. Value types are always copied, so location never applies to them. Reference types need a location whenever they appear as local variables, parameters, or return values, because Solidity needs to know whether to create a reference or a copy.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;code&gt;storage&lt;&#x2F;code&gt; when you need to modify state. Use &lt;code&gt;calldata&lt;&#x2F;code&gt; for external inputs you will not modify. Use &lt;code&gt;memory&lt;&#x2F;code&gt; for everything else.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gas and Gas Price in Solidity</title>
        <published>2025-11-01T00:00:00+00:00</published>
        <updated>2025-11-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/gas-and-gas-price-in-solidity/"/>
        <id>https://akash11.com/blog/gas-and-gas-price-in-solidity/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/gas-and-gas-price-in-solidity/">&lt;p&gt;Gas is the unit that measures computational effort on the Ethereum network. Every operation your smart contract performs costs gas, and gas costs real money paid in ETH. If your contract is inefficient, it becomes expensive for users to interact with. During periods of network congestion, the same transaction can cost 10x more than during quiet periods.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains how gas works, how to set gas limits correctly, and how to cut storage costs using variable packing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-gas-and-how-is-cost-calculated&quot;&gt;What is Gas and How is Cost Calculated&lt;&#x2F;h2&gt;
&lt;p&gt;Every time a user calls a function or deploys a contract, the EVM executes your code across thousands of nodes. Those nodes need compensation for their work. Gas is how that compensation is measured and charged.&lt;&#x2F;p&gt;
&lt;p&gt;The formula is simple:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Transaction Cost = Gas Used x Gas Price&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Gas price is measured in gwei. One gwei equals 0.000000001 ETH. During peak network usage, gas prices can swing from 20 gwei to 200 gwei or higher. The same operation that costs $2 at 20 gwei can cost $20 at 200 gwei.&lt;&#x2F;p&gt;
&lt;p&gt;Not all operations cost the same amount of gas. Here is a rough breakdown of common EVM operations:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Gas Cost&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Basic arithmetic&lt;&#x2F;td&gt;&lt;td&gt;3 gas&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Reading from storage (cold)&lt;&#x2F;td&gt;&lt;td&gt;2100 gas&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Writing to storage (new value)&lt;&#x2F;td&gt;&lt;td&gt;20000 gas&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Writing to storage (update)&lt;&#x2F;td&gt;&lt;td&gt;5000 gas&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Event emission&lt;&#x2F;td&gt;&lt;td&gt;~375 gas per topic&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Storage operations are by far the most expensive. Designing your contract to minimize storage reads and writes is the single most impactful optimization you can make.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-gas-limits-work&quot;&gt;How Gas Limits Work&lt;&#x2F;h2&gt;
&lt;p&gt;The gas limit is the maximum gas you are willing to spend on a transaction. It exists to protect you from runaway execution. Without a limit, a bug causing an infinite loop would drain your wallet completely.&lt;&#x2F;p&gt;
&lt;p&gt;There are two kinds of gas limits you need to understand:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Block gas limit&lt;&#x2F;strong&gt; is set by the network&#x27;s validators. It caps the total gas allowed across all transactions in one block. On Ethereum mainnet this is around 30 million gas. It determines how many transactions can fit in a block.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Transaction gas limit&lt;&#x2F;strong&gt; is the value you set when sending a transaction. This is what you control.&lt;&#x2F;p&gt;
&lt;p&gt;Here is exactly what happens when you submit a transaction:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;You set a gas limit (say, 100000 gas)&lt;&#x2F;li&gt;
&lt;li&gt;You set a gas price (say, 50 gwei)&lt;&#x2F;li&gt;
&lt;li&gt;Your wallet reserves 100000 x 50 = 5000000 gwei (0.005 ETH)&lt;&#x2F;li&gt;
&lt;li&gt;The transaction executes and uses actual gas (say, 65000)&lt;&#x2F;li&gt;
&lt;li&gt;You pay for 65000 x 50 = 3250000 gwei (0.00325 ETH)&lt;&#x2F;li&gt;
&lt;li&gt;The remaining 35000 gas is refunded&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The important thing to understand: if your transaction runs out of gas before completing, the EVM reverts all state changes but you do not get the gas back. You pay for the work done up to the point of failure.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; GasLimitDemo&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; numbers;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Gas cost grows with each iteration&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Calling addNumbers(1000) needs far more gas than addNumbers(10)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; addNumbers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; count&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; count; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;            numbers.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(i);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you call &lt;code&gt;addNumbers(1000)&lt;&#x2F;code&gt; with a gas limit of 100000 but the function needs 500000 gas, the transaction fails at the limit, all changes revert, and you pay for the gas consumed up to 100000.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Failed transactions still cost gas. Setting the gas limit too low does not save money. It wastes money on failed attempts while leaving state unchanged.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;setting-the-right-gas-limit&quot;&gt;Setting the Right Gas Limit&lt;&#x2F;h3&gt;
&lt;p&gt;Most wallets estimate gas automatically, but their estimates can be wrong for complex or loop-heavy functions. You can add a safety buffer in your scripts:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Estimate gas then add 20% buffer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; gasEstimate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; await&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;riskyOperation&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;estimateGas&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; safeLimit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;floor&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;gasEstimate&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 1.2&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A 10-20% buffer is standard practice. For functions with variable loop counts, test with realistic inputs before deploying.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;avoiding-unbounded-loops&quot;&gt;Avoiding Unbounded Loops&lt;&#x2F;h3&gt;
&lt;p&gt;The most common cause of out-of-gas failures is iterating over an array whose size can grow without bound.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;bad-pattern.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; BadPattern&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; users;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; DANGEROUS: gas cost is unknown and grows over time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processAll&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &amp;lt; users.length; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; process each user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;good-pattern.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; GoodPattern&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt;[]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; users;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; SAFE: caller controls the batch size&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; processBatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; start&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; end&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(end &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; users.length,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Out of bounds&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(end &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; start &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Batch too large&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; start; i &amp;lt; end; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;            &#x2F;&#x2F; process user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The batch pattern lets you process large arrays across multiple transactions without hitting the block gas limit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;checking-remaining-gas-at-runtime&quot;&gt;Checking Remaining Gas at Runtime&lt;&#x2F;h3&gt;
&lt;p&gt;For complex operations, you can read remaining gas mid-execution and bail out early if you are running low:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; GasAware&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; complexOperation&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;gasleft&lt;&#x2F;span&gt;&lt;span&gt;() &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100000&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Not enough gas provided&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; perform expensive work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;gasleft&lt;&#x2F;span&gt;&lt;span&gt;() &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 50000&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;Insufficient gas to complete safely&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Use &lt;code&gt;gasleft()&lt;&#x2F;code&gt; sparingly. It is useful for guard rails in loops or multi-step operations, but it adds complexity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;variable-packing-for-storage-optimization&quot;&gt;Variable Packing for Storage Optimization&lt;&#x2F;h2&gt;
&lt;p&gt;Storage is the most expensive part of a Solidity contract. Variable packing is a technique that reduces the number of storage slots your contract uses, which directly reduces gas costs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-evm-storage-works&quot;&gt;How EVM Storage Works&lt;&#x2F;h3&gt;
&lt;p&gt;The EVM stores state variables in 32-byte (256-bit) slots. Reading or writing a slot costs the same amount of gas whether you use 1 byte or all 32 bytes. If you declare your variables carelessly, you can waste entire slots on variables that only need a few bytes.&lt;&#x2F;p&gt;
&lt;p&gt;Consider this unpacked layout:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;bad-packing.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UnpackedStorage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0: uses 1 byte, 31 bytes wasted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 1: full 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; c;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 2: uses 1 byte, 31 bytes wasted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; d;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 3: full 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; e;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 4: uses 1 byte, 31 bytes wasted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; 5 storage slots = 5 x 20000 = 100000 gas to initialize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now the same data, packed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;good-packing.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PackedStorage&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0, byte 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; c;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0, byte 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; e;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0, byte 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 1: full 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; d;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 2: full 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; 3 storage slots = 3 x 20000 = 60000 gas to initialize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Saves 40000 gas (40% reduction)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The EVM packs variables into the same slot automatically, but only if they are declared sequentially and fit together. Declaration order matters.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;common-variable-sizes&quot;&gt;Common Variable Sizes&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Type&lt;&#x2F;th&gt;&lt;th&gt;Size&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;bool&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1 byte&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uint8&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;1 byte&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uint16&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;2 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uint32&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;4 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uint64&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;8 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uint128&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;16 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uint256&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;32 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;address&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;20 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;bytes32&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;32 bytes&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;practical-examples&quot;&gt;Practical Examples&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Token contract storage layout:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;token-bad.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; BAD: 4 storage slots = 80000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TokenBad&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;       &#x2F;&#x2F; Slot 0: 20 bytes + 12 bytes wasted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; totalSupply;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Slot 1: 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; paused;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;         &#x2F;&#x2F; Slot 2: 1 byte + 31 bytes wasted&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; lastUpdate;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 3: 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;token-good.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; GOOD: 3 storage slots = 60000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TokenGood&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;       &#x2F;&#x2F; Slot 0: 20 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; paused;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;         &#x2F;&#x2F; Slot 0: 1 byte (packed with owner)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; totalSupply;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Slot 1: 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; lastUpdate;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 2: 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Saves 20000 gas per deployment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;User profile with many small fields:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;user-profile.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; BAD: 7 slots = 140000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UserProfileBad&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; userId;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; age;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;         &#x2F;&#x2F; Slot 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isActive;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint16&lt;&#x2F;span&gt;&lt;span&gt; reputation;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Slot 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; wallet;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint32&lt;&#x2F;span&gt;&lt;span&gt; joinDate;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; Slot 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isPremium;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; GOOD: 3 slots = 60000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UserProfileGood&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; userId;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0: 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 1: 20 + 4 + 2 + 1 + 1 + 1 = 29 bytes (fits in 32)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; wallet;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 1: 20 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint32&lt;&#x2F;span&gt;&lt;span&gt; joinDate;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; Slot 1: 4 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint16&lt;&#x2F;span&gt;&lt;span&gt; reputation;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Slot 1: 2 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; age;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;         &#x2F;&#x2F; Slot 1: 1 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isActive;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 1: 1 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isPremium;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 1: 1 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Saves 80000 gas per user (57% reduction)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;packing-rules-for-structs-and-mappings&quot;&gt;Packing Rules for Structs and Mappings&lt;&#x2F;h3&gt;
&lt;p&gt;Structs follow the same packing rules as contract-level variables:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; BadStruct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 1 (breaks packing)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; c;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; GoodStruct&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; c;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 0 (packed)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Mappings and dynamic arrays always start a new storage slot and cannot be packed with adjacent variables:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; MappingLayout&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint128&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;                   &#x2F;&#x2F; Slot 0, first 16 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint128&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;                   &#x2F;&#x2F; Slot 0, last 16 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;) c;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 1 (always starts new slot)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint128&lt;&#x2F;span&gt;&lt;span&gt; d;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;                   &#x2F;&#x2F; Slot 2 (cannot pack with mapping)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;real-world-example-nft-struct&quot;&gt;Real-World Example: NFT Struct&lt;&#x2F;h3&gt;
&lt;p&gt;Here is how packing applies to a token struct in an NFT contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;nft-before.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; BEFORE: 8 slots per token = 160000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; Slot 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; approved;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; price;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isListed;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; rarity;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;      &#x2F;&#x2F; Slot 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint32&lt;&#x2F;span&gt;&lt;span&gt; mintedAt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; Slot 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint16&lt;&#x2F;span&gt;&lt;span&gt; generation;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Slot 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;nft-after.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; AFTER: 4 slots per token = 80000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; tokenId;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; Slot 0: 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; price;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 1: 32 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot 2: 20 + 4 + 2 + 1 + 1 = 28 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 2: 20 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint32&lt;&#x2F;span&gt;&lt;span&gt; mintedAt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; Slot 2: 4 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint16&lt;&#x2F;span&gt;&lt;span&gt; generation;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Slot 2: 2 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span&gt; rarity;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;      &#x2F;&#x2F; Slot 2: 1 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot; style=&quot;background-color: #2C313C;&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span&gt; isListed;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;     &#x2F;&#x2F; Slot 2: 1 byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span&gt; approved;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; Slot 3: 20 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Saves 80000 gas per token (50% reduction)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; For 10000 NFTs: 800 million gas saved in total&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-tradeoff-packing-adds-computation&quot;&gt;The Tradeoff: Packing Adds Computation&lt;&#x2F;h3&gt;
&lt;p&gt;Packing is not free. When you read or write a packed variable, the EVM has to read the full 32-byte slot, extract your variable with bitwise operations, modify it, and write the slot back. This adds a small computation cost.&lt;&#x2F;p&gt;
&lt;p&gt;In practice, packing is almost always worth it because storage operations are so much more expensive than arithmetic. Here is a concrete comparison:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;packed.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; PackedUpdate&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint128&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint128&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; updateBoth&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newB&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newA;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; First write to slot 0: 20000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newB;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Second write to same slot (warm): 5000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Total: 25000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;unpacked.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; UnpackedUpdate&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; a;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; updateBoth&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newA&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newB&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newA;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Write to slot 0: 20000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        b &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newB;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Write to slot 1: 20000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Total: 40000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The packed version saves 15000 gas even accounting for the extra computation. The exception is when two packed variables are always read or written independently and rarely together. In that case, packing may add overhead without benefit. Measure before assuming.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-optimization-techniques&quot;&gt;Other Optimization Techniques&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;cache-storage-reads-in-memory&quot;&gt;Cache Storage Reads in Memory&lt;&#x2F;h3&gt;
&lt;p&gt;Every time you read a storage variable, it costs 2100 gas (cold) or 100 gas (warm). If you read the same variable multiple times in a function, cache it in a local memory variable first.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Cache the balance once instead of reading storage twice&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span&gt; senderBalance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(senderBalance &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senderBalance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;use-events-for-data-you-do-not-need-on-chain&quot;&gt;Use Events for Data You Do Not Need On-Chain&lt;&#x2F;h3&gt;
&lt;p&gt;If you need to record something for off-chain use but never read it inside the contract, use events. They cost roughly 375 gas per indexed topic, far cheaper than a storage write.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; state changes here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, to, amount);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; ~1500 gas total&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;storage-refunds&quot;&gt;Storage Refunds&lt;&#x2F;h3&gt;
&lt;p&gt;Setting a storage slot to zero gives you a gas refund of 15000 gas. This makes cleanup functions cheaper to run.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; close&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    delete&lt;&#x2F;span&gt;&lt;span&gt; balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt; &#x2F;&#x2F; Refunds 15000 gas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Refunds are capped at 20% of total gas used for the transaction, so you cannot refund more than you spent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;putting-it-together-an-optimized-token-contract&quot;&gt;Putting It Together: An Optimized Token Contract&lt;&#x2F;h2&gt;
&lt;p&gt;This example combines the techniques covered above into a working token contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;optimized-token.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; OptimizedToken&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Dynamic strings take their own slots&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; name;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; symbol;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; totalSupply;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Slot: 20 + 1 + 1 = 22 bytes, packed together&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; paused;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; decimals;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; private&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; indexed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(!paused,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Contract is paused&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Read storage once, use local variable for checks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; senderBalance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(senderBalance &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; senderBalance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;        balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        emit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;, to, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The contract packs &lt;code&gt;owner&lt;&#x2F;code&gt;, &lt;code&gt;paused&lt;&#x2F;code&gt;, and &lt;code&gt;decimals&lt;&#x2F;code&gt; into one slot, caches the sender balance to avoid a redundant storage read, and uses an event for the transfer log instead of extra storage.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Gas optimization is not premature optimization. In Ethereum, every byte you waste costs your users real money. The two techniques covered here give you the most leverage:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Gas limits&lt;&#x2F;strong&gt; protect you from runaway transactions. Always add a 10-20% buffer on top of estimated gas. Never write unbounded loops. Use batching when you need to process large arrays.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Variable packing&lt;&#x2F;strong&gt; cuts storage costs by filling each 32-byte slot fully. Declare small types together, group related fields in structs, and remember that mappings always start a new slot. For a large NFT collection or a frequently-updated contract, the savings compound quickly.&lt;&#x2F;p&gt;
&lt;p&gt;Start with packing your storage layout before deployment. It costs nothing at that stage and the savings are permanent.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>View and Pure Functions in Solidity</title>
        <published>2025-11-01T00:00:00+00:00</published>
        <updated>2025-11-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/view-and-pure-functions-in-solidity/"/>
        <id>https://akash11.com/blog/view-and-pure-functions-in-solidity/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/view-and-pure-functions-in-solidity/">&lt;p&gt;Solidity gives you two function modifiers, &lt;code&gt;view&lt;&#x2F;code&gt; and &lt;code&gt;pure&lt;&#x2F;code&gt;, that let you declare upfront whether a function reads or modifies blockchain state. The compiler enforces these declarations, which means bugs get caught early and other developers can understand your code at a glance.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains what each modifier does, what counts as reading or modifying state, and when to use each one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-state-means-in-a-smart-contract&quot;&gt;What &quot;State&quot; Means in a Smart Contract&lt;&#x2F;h2&gt;
&lt;p&gt;State is any data stored permanently on the blockchain. This includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Storage variables declared at the contract level&lt;&#x2F;li&gt;
&lt;li&gt;Account balances (including &lt;code&gt;address(this).balance&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Data in other contracts&lt;&#x2F;li&gt;
&lt;li&gt;Block and transaction context (&lt;code&gt;block.timestamp&lt;&#x2F;code&gt;, &lt;code&gt;msg.sender&lt;&#x2F;code&gt;, etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Reading or writing state costs gas. Functions that interact with state need to be part of a transaction, and transactions cost gas. Functions that do not touch state can sometimes be executed off-chain for free.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;view-functions&quot;&gt;View Functions&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;code&gt;view&lt;&#x2F;code&gt; function promises it will read state but never modify it. The compiler enforces this. If your function tries to write to a storage variable or emit an event, it will not compile as &lt;code&gt;view&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Counter.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Counter&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; count &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Reads state, returns it unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getCount&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; count;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Reads state and does a calculation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getDoubleCount&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; count &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When you call a &lt;code&gt;view&lt;&#x2F;code&gt; function directly from outside the blockchain (using &lt;code&gt;eth_call&lt;&#x2F;code&gt;), it costs no gas. The node executes it locally and returns the result. However, if a regular state-changing function calls a &lt;code&gt;view&lt;&#x2F;code&gt; function internally during a transaction, that internal call still consumes gas as part of the overall transaction cost.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pure-functions&quot;&gt;Pure Functions&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;code&gt;pure&lt;&#x2F;code&gt; function is more restricted than &lt;code&gt;view&lt;&#x2F;code&gt;. It cannot read state and cannot modify state. It only works with its input parameters.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;MathHelper.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; MathHelper&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; No state read, no state write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; multiply&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; y&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; x &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; y;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;pure&lt;&#x2F;code&gt; functions are useful for utility logic: hashing, encoding, arithmetic, or any computation that does not depend on contract data. Because they have no side effects and no dependencies on storage, they behave like mathematical functions. Same input always produces same output.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-breaks-each-promise&quot;&gt;What Breaks Each Promise&lt;&#x2F;h2&gt;
&lt;p&gt;These actions will cause the compiler to reject a &lt;code&gt;view&lt;&#x2F;code&gt; or &lt;code&gt;pure&lt;&#x2F;code&gt; declaration.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Breaks &lt;code&gt;view&lt;&#x2F;code&gt; (modifies state):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Writing to a storage variable&lt;&#x2F;li&gt;
&lt;li&gt;Emitting an event&lt;&#x2F;li&gt;
&lt;li&gt;Creating another contract&lt;&#x2F;li&gt;
&lt;li&gt;Using &lt;code&gt;selfdestruct&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Sending Ether&lt;&#x2F;li&gt;
&lt;li&gt;Calling a function that is not &lt;code&gt;view&lt;&#x2F;code&gt; or &lt;code&gt;pure&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Using low-level calls (&lt;code&gt;call&lt;&#x2F;code&gt;, &lt;code&gt;delegatecall&lt;&#x2F;code&gt;, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Writing state via inline assembly&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Breaks &lt;code&gt;pure&lt;&#x2F;code&gt; (reads state):&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reading a storage variable&lt;&#x2F;li&gt;
&lt;li&gt;Accessing &lt;code&gt;address(this).balance&lt;&#x2F;code&gt; or any other address balance&lt;&#x2F;li&gt;
&lt;li&gt;Accessing &lt;code&gt;block&lt;&#x2F;code&gt;, &lt;code&gt;tx&lt;&#x2F;code&gt;, or &lt;code&gt;msg&lt;&#x2F;code&gt; properties (except &lt;code&gt;msg.sig&lt;&#x2F;code&gt; and &lt;code&gt;msg.data&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Calling a function that is not &lt;code&gt;pure&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Reading state via inline assembly&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
&lt;p&gt;&lt;code&gt;msg.sig&lt;&#x2F;code&gt; and &lt;code&gt;msg.data&lt;&#x2F;code&gt; are allowed inside &lt;code&gt;pure&lt;&#x2F;code&gt; functions. They describe the call itself, not the blockchain state.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;all-three-types-together&quot;&gt;All Three Types Together&lt;&#x2F;h2&gt;
&lt;p&gt;Here is a single contract showing a state-modifying function, a &lt;code&gt;view&lt;&#x2F;code&gt; function, and a &lt;code&gt;pure&lt;&#x2F;code&gt; function side by side:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Example.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Example&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; storedNumber &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Regular function: modifies state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; setNumber&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; newNumber&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;        storedNumber &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; newNumber;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; View function: reads state, no modification&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getNumber&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; storedNumber;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; View function: reads state and transforms it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; getNumberPlusTen&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; storedNumber &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Pure function: no state involved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; a&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public pure returns&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;why-this-matters&quot;&gt;Why This Matters&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Gas savings.&lt;&#x2F;strong&gt; External calls to &lt;code&gt;view&lt;&#x2F;code&gt; and &lt;code&gt;pure&lt;&#x2F;code&gt; functions execute off-chain for free when called directly. If your frontend or another service only needs to read data, declaring the function as &lt;code&gt;view&lt;&#x2F;code&gt; lets callers skip the transaction entirely.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Compiler enforcement.&lt;&#x2F;strong&gt; The compiler will reject a &lt;code&gt;view&lt;&#x2F;code&gt; function that tries to write state, and reject a &lt;code&gt;pure&lt;&#x2F;code&gt; function that tries to read it. This catches an entire class of accidental side effects before deployment.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Readability.&lt;&#x2F;strong&gt; A developer reading your code does not need to trace through the function body to understand whether it modifies anything. The keyword says it upfront.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-to-use-each&quot;&gt;When to Use Each&lt;&#x2F;h2&gt;
&lt;p&gt;Use a regular function when you need to write to storage, emit events, or change contract state in any way.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;code&gt;view&lt;&#x2F;code&gt; when you need to read storage variables, balances, or block context without changing anything.&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;code&gt;pure&lt;&#x2F;code&gt; when your function only needs its input parameters, nothing from storage or the environment.&lt;&#x2F;p&gt;
&lt;p&gt;If you are unsure which to use, start with &lt;code&gt;pure&lt;&#x2F;code&gt;. If the compiler rejects it because you are reading state, upgrade to &lt;code&gt;view&lt;&#x2F;code&gt;. If the compiler rejects that because you are writing state, remove the modifier entirely.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Custom Errors in Solidity: Lower Gas, Cleaner Code</title>
        <published>2025-10-20T00:00:00+00:00</published>
        <updated>2025-10-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/solidity-custom-errors-gas-savings/"/>
        <id>https://akash11.com/blog/solidity-custom-errors-gas-savings/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/solidity-custom-errors-gas-savings/">&lt;p&gt;Solidity 0.8.4 introduced custom errors. They are a direct replacement for &lt;code&gt;require&lt;&#x2F;code&gt; statements with string messages. The benefit is straightforward: lower gas costs, both at deployment and at runtime.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains how custom errors work, how much gas they save and why, and how to migrate existing contracts to use them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem-with-string-errors&quot;&gt;The Problem with String Errors&lt;&#x2F;h2&gt;
&lt;p&gt;The traditional pattern for error handling in Solidity looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; OldWayErrors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; restrictedFunction&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; == owner,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Only owner can call this function&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every string you pass to &lt;code&gt;require&lt;&#x2F;code&gt; gets embedded in the contract bytecode. The longer the string, the more bytes are stored on-chain. This affects deployment cost directly. Multiply that across a contract with 10 or 20 functions, each with one or more require checks, and the bytecode bloat becomes significant.&lt;&#x2F;p&gt;
&lt;p&gt;At runtime, reverting with a string message means the EVM must ABI-encode that string and return it as revert data. That encoding costs gas on every failed transaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-custom-errors-work&quot;&gt;How Custom Errors Work&lt;&#x2F;h2&gt;
&lt;p&gt;A custom error is declared at the contract level using the &lt;code&gt;error&lt;&#x2F;code&gt; keyword. When a condition fails, you use &lt;code&gt;revert&lt;&#x2F;code&gt; with that error instead of &lt;code&gt;require&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; NewWayErrors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Unauthorized&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; restrictedFunction&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public view&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; != owner) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Unauthorized&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Under the hood, Solidity hashes the error signature (for example, &lt;code&gt;Unauthorized()&lt;&#x2F;code&gt;) and takes the first 4 bytes. This is the same mechanism used for function selectors. When the transaction reverts, those 4 bytes are returned as the revert data instead of an encoded string.&lt;&#x2F;p&gt;
&lt;p&gt;4 bytes versus dozens or hundreds of bytes per error. That is where the savings come from.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-savings-deployment&quot;&gt;Gas Savings: Deployment&lt;&#x2F;h2&gt;
&lt;p&gt;Consider a contract with several common validation checks:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;TraditionalErrors.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TraditionalErrors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(to !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Cannot transfer to zero address&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(amount &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Amount must be greater than zero&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;        balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Those three strings total around 80 characters. Each character is one byte in the bytecode. In a real contract with many functions, this adds up fast.&lt;&#x2F;p&gt;
&lt;p&gt;Now the same logic with custom errors:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;ModernErrors.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ModernErrors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ZeroAddress&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; InvalidAmount&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (to ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ZeroAddress&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;lt; amount)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (amount ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; InvalidAmount&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each error declaration contributes only a 4-byte selector to the bytecode. You can also reuse the same error in multiple functions without duplicating anything. Across a full contract, the deployment cost reduction typically falls between 5,000 and 15,000 gas depending on how many string messages you had and how long they were.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-savings-runtime&quot;&gt;Gas Savings: Runtime&lt;&#x2F;h2&gt;
&lt;p&gt;When a transaction reverts, the EVM returns revert data to the caller. With a string message, that data includes the full ABI-encoded string. With a custom error, it is just the 4-byte selector.&lt;&#x2F;p&gt;
&lt;p&gt;The runtime saving per revert is smaller than the deployment saving, typically 20 to 50 gas. But for a protocol processing a high volume of transactions where a percentage of them revert (failed transfers, access control checks, slippage limits), that saving compounds across every failed call over the contract&#x27;s lifetime.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-parameters-to-custom-errors&quot;&gt;Adding Parameters to Custom Errors&lt;&#x2F;h2&gt;
&lt;p&gt;Custom errors support parameters. This lets you include useful context in a revert without the overhead of string formatting.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; AdvancedErrors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; available,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; required);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TransferFailed&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; from,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt; to,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint256&lt;&#x2F;span&gt;&lt;span&gt; balance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (balance &amp;lt; amount) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(balance, amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;        balances[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The parameters are ABI-encoded and included in the revert data. The base cost is still lower than a string revert, because you avoid the fixed overhead of encoding a string type. And the error is more precise: a caller or interface can decode the exact values that caused the failure.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
&lt;p&gt;Adding parameters does increase the revert data size compared to a parameter-less custom error. The savings compared to an equivalent &lt;code&gt;require&lt;&#x2F;code&gt; with a formatted string are still present, but smaller. For the tightest gas optimisation, prefer parameter-less errors on hot paths.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;organising-errors-in-a-real-contract&quot;&gt;Organising Errors in a Real Contract&lt;&#x2F;h2&gt;
&lt;p&gt;For contracts with many error cases, group errors by category at the top of the contract:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;TokenWithErrors.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TokenWithErrors&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Access control&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Unauthorized&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; NotOwner&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Transfer validation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ZeroAddress&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint256&lt;&#x2F;span&gt;&lt;span&gt; available,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span&gt; required);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; TransferToSelf&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Contract state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; ContractPaused&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; AlreadyInitialized&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; ... implementation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This makes the error surface of a contract easy to read at a glance. Tools like Etherscan decode custom errors automatically, so users and developers still get meaningful information when a transaction fails. The 4-byte selector maps back to the human-readable error name in any ABI-aware tool.&lt;&#x2F;p&gt;
&lt;p&gt;A function with multiple checks reads cleanly with the &lt;code&gt;if-revert&lt;&#x2F;code&gt; pattern:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; complexOperation&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; target&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint256&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (target ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ZeroAddress&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; != owner)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Unauthorized&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (paused)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; ContractPaused&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (value &amp;gt; maxValue)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; InvalidAmount&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; operation logic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;testing-custom-errors&quot;&gt;Testing Custom Errors&lt;&#x2F;h2&gt;
&lt;p&gt;In Foundry, use &lt;code&gt;vm.expectRevert&lt;&#x2F;code&gt; with the error selector:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; testUnauthorizedAccess&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;    vm.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;expectRevert&lt;&#x2F;span&gt;&lt;span&gt;(Unauthorized.selector);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;    myContract.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;restrictedFunction&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For errors with parameters, encode the full expected revert data:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; testInsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;    vm.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;expectRevert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        abi&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;encodeWithSelector&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;            MyContract.InsufficientBalance.selector,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;            0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;   &#x2F;&#x2F; available&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt;            100&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;  &#x2F;&#x2F; required&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    myContract.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;transfer&lt;&#x2F;span&gt;&lt;span&gt;(recipient,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In Hardhat with Ethers.js, you can match against the error name directly using &lt;code&gt;.revertedWithCustomError()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    contract&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;restrictedFunction&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;to&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;be&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;revertedWithCustomError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Unauthorized&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;compatibility&quot;&gt;Compatibility&lt;&#x2F;h2&gt;
&lt;p&gt;Custom errors require Solidity 0.8.4 or later. If your project still targets an earlier compiler version, you cannot use them. Most active projects have moved past 0.8.4, so this is rarely a blocker in practice.&lt;&#x2F;p&gt;
&lt;p&gt;Hardhat, Foundry, and Ethers.js all support custom error decoding. Block explorers handle them correctly. The toolchain support is solid.&lt;&#x2F;p&gt;
&lt;p&gt;One thing to be aware of: if your contract inherits from external libraries or interfaces that still use &lt;code&gt;require&lt;&#x2F;code&gt; with strings, those strings will still appear in the bytecode from those dependencies. Custom errors only replace the errors you write yourself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;migration-strategy&quot;&gt;Migration Strategy&lt;&#x2F;h2&gt;
&lt;p&gt;If you have an existing contract you want to convert, prioritise the highest-value changes first:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Identify functions that are called frequently or that revert often (access control checks, balance checks, slippage guards).&lt;&#x2F;li&gt;
&lt;li&gt;Replace those &lt;code&gt;require&lt;&#x2F;code&gt; statements first.&lt;&#x2F;li&gt;
&lt;li&gt;Add parameters to errors where the caller or a frontend needs the failed values to handle the revert properly.&lt;&#x2F;li&gt;
&lt;li&gt;Replace the remaining require statements for consistency.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There is no need to convert everything at once. A contract can mix &lt;code&gt;require&lt;&#x2F;code&gt; strings and custom errors. The two approaches are compatible at the bytecode level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Custom errors are a simple, low-effort optimisation with real impact. Deployment costs drop because string bytecode is replaced by 4-byte selectors. Runtime costs drop because revert data is smaller. Code clarity improves because error names are precise and reusable across functions.&lt;&#x2F;p&gt;
&lt;p&gt;The pattern is well-supported across the Solidity toolchain and has become standard practice in modern contract development. If you are writing new contracts or have the opportunity to audit existing ones, switching to custom errors is one of the easiest improvements you can make.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Error Handling in Solidity: require, revert, assert, and Custom Errors</title>
        <published>2025-10-20T00:00:00+00:00</published>
        <updated>2025-10-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/solidity-error-handling-require-revert-assert-custom-errors/"/>
        <id>https://akash11.com/blog/solidity-error-handling-require-revert-assert-custom-errors/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/solidity-error-handling-require-revert-assert-custom-errors/">&lt;p&gt;Solidity gives you four ways to stop execution when something goes wrong: &lt;code&gt;require&lt;&#x2F;code&gt;, &lt;code&gt;revert&lt;&#x2F;code&gt;, &lt;code&gt;assert&lt;&#x2F;code&gt;, and custom errors. Each one serves a different purpose. Using the wrong one does not break your contract, but it makes your code harder to read and costs more gas than necessary.&lt;&#x2F;p&gt;
&lt;p&gt;This post explains what each mechanism does, when to reach for it, and how they compare in terms of gas cost.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-happens-when-an-error-fires&quot;&gt;What Happens When an Error Fires&lt;&#x2F;h2&gt;
&lt;p&gt;Before Solidity 0.8.0, failed operations could silently continue or produce unpredictable results. That changed in 0.8.0. Now, all four error mechanisms do the same thing at the EVM level: they revert the transaction, roll back every state change made during that call, and refund the remaining gas to the caller.&lt;&#x2F;p&gt;
&lt;p&gt;The difference between them is not what they do when they fail, it is what they signal to readers of your code, and how much gas the failure itself costs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;require-validate-inputs-and-preconditions&quot;&gt;require: Validate Inputs and Preconditions&lt;&#x2F;h2&gt;
&lt;p&gt;Use &lt;code&gt;require&lt;&#x2F;code&gt; to check conditions that depend on external input or state that your contract does not control. The pattern is: if this condition is not met, there is no point continuing.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(amount &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Amount must be positive&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; amount,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Insufficient balance&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;.call{value: amount}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Transfer failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The first two &lt;code&gt;require&lt;&#x2F;code&gt; calls validate inputs before any state is modified. The third one verifies the result of an external call after it returns. All three are valid uses.&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;code&gt;require&lt;&#x2F;code&gt; fails, it reverts the transaction and returns the error string to the caller. This string is what appears in most wallets and block explorers when a transaction fails.&lt;&#x2F;p&gt;
&lt;p&gt;Good places to use &lt;code&gt;require&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Checking &lt;code&gt;msg.sender&lt;&#x2F;code&gt;, &lt;code&gt;msg.value&lt;&#x2F;code&gt;, or function arguments&lt;&#x2F;li&gt;
&lt;li&gt;Verifying return values from external calls (&lt;code&gt;token.transfer&lt;&#x2F;code&gt;, &lt;code&gt;call&lt;&#x2F;code&gt;, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Enforcing access control at the start of a function&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;revert-explicit-control-flow&quot;&gt;revert: Explicit Control Flow&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;revert&lt;&#x2F;code&gt; does the same thing as a failing &lt;code&gt;require&lt;&#x2F;code&gt;, it stops execution and rolls back state. The difference is where you can place it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;require&lt;&#x2F;code&gt; works well at the top of a function where you can check a single condition. Inside nested &lt;code&gt;if&lt;&#x2F;code&gt; statements, it gets awkward. &lt;code&gt;revert&lt;&#x2F;code&gt; fits naturally there.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; buyTicket&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; ticketId&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value &amp;lt; ticketPrice) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;Payment too low&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (tickets[ticketId].sold) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        revert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;Ticket already sold&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;    tickets[ticketId].owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    tickets[ticketId].sold &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can also call &lt;code&gt;revert()&lt;&#x2F;code&gt; without a message. This saves a small amount of gas because no string is encoded into the revert data. The tradeoff is that the caller gets no information about what went wrong, useful only in cases where the revert reason is obvious from context.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assert-internal-invariant-checks&quot;&gt;assert: Internal Invariant Checks&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;assert&lt;&#x2F;code&gt; is for conditions that should never be false if your contract logic is correct. It checks internal invariants, not user inputs, not external state, but properties that your own code must maintain.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; transfer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; to&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span&gt; senderBefore &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span&gt; recipientBefore &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; balance[to];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    balance[to]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;    &#x2F;&#x2F; Total balance must be conserved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span&gt;(balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; balance[to] == senderBefore &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; recipientBefore);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If an &lt;code&gt;assert&lt;&#x2F;code&gt; fires in production, it means your contract has a bug. It is not for validating user input. It is a signal to yourself and to auditors: &quot;this must always be true, if it is not, something is fundamentally broken.&quot;&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Before Solidity 0.8.0, a failed &lt;code&gt;assert&lt;&#x2F;code&gt; consumed all remaining gas. In 0.8.0 and later, it behaves like &lt;code&gt;require&lt;&#x2F;code&gt; in terms of gas refunds. If you are working with older contracts, be aware of this difference.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;custom-errors-gas-efficient-error-handling&quot;&gt;Custom Errors: Gas-Efficient Error Handling&lt;&#x2F;h2&gt;
&lt;p&gt;Custom errors were introduced in Solidity 0.8.4. They give you the control of &lt;code&gt;revert&lt;&#x2F;code&gt; with significantly lower gas cost compared to string-based errors.&lt;&#x2F;p&gt;
&lt;p&gt;Define them at the file or contract level, then use them with &lt;code&gt;revert&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Wallet.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; available,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt; requested);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Unauthorized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; caller);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Wallet&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balance;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; != owner) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; Unauthorized&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;lt; amount) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; InsufficientBalance&lt;&#x2F;span&gt;&lt;span&gt;(balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;], amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span&gt;        balance[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Custom errors can carry parameters. When the transaction reverts, the caller receives typed data, the exact values that caused the failure, rather than a plain string. This makes debugging easier on both the contract side and the frontend side.&lt;&#x2F;p&gt;
&lt;p&gt;The gas saving comes from how Solidity encodes errors. A string like &lt;code&gt;&quot;Insufficient balance&quot;&lt;&#x2F;code&gt; is stored in the contract bytecode and encoded into the revert data at runtime. A custom error uses a 4-byte selector (the first four bytes of the keccak256 hash of the error signature), plus ABI-encoded parameters. This is significantly cheaper, especially for errors with long messages.&lt;&#x2F;p&gt;
&lt;p&gt;Custom errors cost roughly 2,000 gas less than an equivalent &lt;code&gt;require&lt;&#x2F;code&gt; with a string message. For a function called thousands of times per day, that is real money.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;choosing-the-right-tool&quot;&gt;Choosing the Right Tool&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Mechanism&lt;&#x2F;th&gt;&lt;th&gt;Use when&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;require&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Validating inputs, checking preconditions, verifying external call results&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;revert&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Complex conditional logic where &lt;code&gt;require&lt;&#x2F;code&gt; would be awkward&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;assert&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Checking invariants that must always hold if your code is correct&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Custom errors&lt;&#x2F;td&gt;&lt;td&gt;Production contracts where gas efficiency matters&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;In most new contracts, the pattern is: &lt;code&gt;require&lt;&#x2F;code&gt; for simple preconditions at function entry, custom errors with &lt;code&gt;revert&lt;&#x2F;code&gt; for everything else, and &lt;code&gt;assert&lt;&#x2F;code&gt; sparingly for internal consistency checks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-complete-example&quot;&gt;A Complete Example&lt;&#x2F;h2&gt;
&lt;p&gt;This contract combines all four mechanisms in realistic ways:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot; data-name=&quot;Vault.sol&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; SPDX-License-Identifier: MIT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;pragma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; solidity&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; ^0.8.4&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; NotOwner&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; InsufficientFunds&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span&gt; available,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt; requested);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;contract&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; Vault&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; owner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    mapping&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; uint&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; balances;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;    uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; totalDeposited;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    constructor&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;        owner &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;15&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; deposit&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public payable&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; require: validates external input (msg.value)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Must deposit something&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;        totalDeposited &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg&lt;&#x2F;span&gt;&lt;span&gt;.value;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;22&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; assert: verifies internal invariant, contract balance must match our accounting&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;).balance == totalDeposited);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; withdraw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt; amount&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; custom error with revert: gas-efficient, carries typed context&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;] &amp;lt; amount) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; InsufficientFunds&lt;&#x2F;span&gt;&lt;span&gt;(balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;], amount);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;        balances[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span&gt;        totalDeposited &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span&gt; amount;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; msg.sender&lt;&#x2F;span&gt;&lt;span&gt;.call{value: amount}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; require: verifies result of external call&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Transfer failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;39&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;).balance == totalDeposited);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;    function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; emergencyWithdraw&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; public&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;44&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;        &#x2F;&#x2F; custom error: cheap, precise&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg.sender&lt;&#x2F;span&gt;&lt;span&gt; != owner) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;            revert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; NotOwner&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;49&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;        uint&lt;&#x2F;span&gt;&lt;span&gt; contractBalance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt; address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;this&lt;&#x2F;span&gt;&lt;span&gt;).balance;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;        totalDeposited &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;51&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;52&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span&gt; success, )&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; owner.call{value: contractBalance}(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;53&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;        require&lt;&#x2F;span&gt;&lt;span&gt;(success,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Emergency withdrawal failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;54&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;55&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that &lt;code&gt;assert&lt;&#x2F;code&gt; appears after state changes, not before. That is intentional. &lt;code&gt;assert&lt;&#x2F;code&gt; checks that the state your code just produced is internally consistent. It is not a replacement for &lt;code&gt;require&lt;&#x2F;code&gt; at the start of a function.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;one-pattern-to-avoid&quot;&gt;One Pattern to Avoid&lt;&#x2F;h2&gt;
&lt;p&gt;A common mistake is using &lt;code&gt;assert&lt;&#x2F;code&gt; for input validation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;solidity&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Wrong, this is input validation, not an invariant&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;&#x2F;&#x2F; Correct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E5C07B;&quot;&gt;msg&lt;&#x2F;span&gt;&lt;span&gt;.value &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;Must send ETH&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The practical consequence in pre-0.8.0 contracts: a failed &lt;code&gt;assert&lt;&#x2F;code&gt; would burn all remaining gas. Even in 0.8.0+, using &lt;code&gt;assert&lt;&#x2F;code&gt; for input validation signals to auditors that you either misunderstand the distinction or have a logic error you are trying to catch. Neither is a good look.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Solidity&#x27;s four error mechanisms share the same outcome, transaction revert, but communicate different things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;require&lt;&#x2F;code&gt; says &quot;the caller did something wrong or the external state is not ready&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;revert&lt;&#x2F;code&gt; says &quot;a condition was not met, and I need explicit control over when to stop&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;assert&lt;&#x2F;code&gt; says &quot;my contract&#x27;s internal state is broken, this should never happen&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Custom errors say all of the above, with less gas and better typed data for callers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Use each for what it was designed for. The distinction matters most when someone else is reading your code, or when an auditor is trying to understand what your contract assumes about the world.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Managing Multiple Node.js Versions with NVM</title>
        <published>2025-08-11T00:00:00+00:00</published>
        <updated>2025-08-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/managing-multiple-node-versions-with-nvm/"/>
        <id>https://akash11.com/blog/managing-multiple-node-versions-with-nvm/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/managing-multiple-node-versions-with-nvm/">&lt;p&gt;If you work on more than one JavaScript project, you have probably hit this problem: one project needs Node 16, another needs Node 20, and the system only has one version installed.&lt;&#x2F;p&gt;
&lt;p&gt;Reinstalling Node every time you switch projects is not a real solution. Node Version Manager (NVM) is. It lets you install multiple Node.js versions on the same machine and switch between them per project or per terminal session.&lt;&#x2F;p&gt;
&lt;p&gt;This post walks through installing NVM, the commands you will use daily, and how to lock versions per project so your whole team stays in sync.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-nvm&quot;&gt;Installing NVM&lt;&#x2F;h2&gt;
&lt;p&gt;Before installing NVM, remove any existing system-wide Node.js installation. A leftover installation can cause PATH conflicts where commands resolve to the wrong binary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;macos-and-linux&quot;&gt;macOS and Linux&lt;&#x2F;h3&gt;
&lt;p&gt;Run the install script using curl:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -o-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;nvm-sh&#x2F;nvm&#x2F;v0.39.7&#x2F;install.sh&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or with wget if you prefer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;wget&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -qO-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;nvm-sh&#x2F;nvm&#x2F;v0.39.7&#x2F;install.sh&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The script adds initialization code to your shell profile automatically. After it finishes, reload your shell:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# For bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ~&#x2F;.bashrc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# For zsh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ~&#x2F;.zshrc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Verify the installation worked:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;windows&quot;&gt;Windows&lt;&#x2F;h3&gt;
&lt;p&gt;NVM does not support Windows natively. A separate project called &lt;code&gt;nvm-windows&lt;&#x2F;code&gt; covers this. Download the installer from &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coreybutler&#x2F;nvm-windows&#x2F;releases&quot;&gt;github.com&#x2F;coreybutler&#x2F;nvm-windows&#x2F;releases&lt;&#x2F;a&gt;, run it, and follow the wizard.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
&lt;p&gt;&lt;code&gt;nvm-windows&lt;&#x2F;code&gt; has slightly different command names from the macOS&#x2F;Linux version. The core workflow is the same, but a few commands differ. This post focuses on macOS&#x2F;Linux. Where Windows commands differ, they are noted.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;installing-node-js-versions&quot;&gt;Installing Node.js Versions&lt;&#x2F;h2&gt;
&lt;p&gt;Once NVM is set up, installing a Node version is one command.&lt;&#x2F;p&gt;
&lt;p&gt;Install the current LTS release:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --lts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Install a specific version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Install the latest release (whatever is newest at the time):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; install node&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;NVM downloads the binary, stores it in &lt;code&gt;~&#x2F;.nvm&#x2F;versions&#x2F;&lt;&#x2F;code&gt;, and makes it active in the current terminal session.&lt;&#x2F;p&gt;
&lt;p&gt;To see every available version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# macOS &#x2F; Linux&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ls-remote&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7F848E;font-style: italic;&quot;&gt;# Windows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; list available&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The output is long. Filter it with &lt;code&gt;grep&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ls-remote&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;v20&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;switching-versions&quot;&gt;Switching Versions&lt;&#x2F;h2&gt;
&lt;p&gt;This is the main use case. Switch to a specific version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Switch to the latest LTS:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --lts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The change applies to the current terminal session only. Open a new terminal and you are back to whatever the default is.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting-a-default-version&quot;&gt;Setting a Default Version&lt;&#x2F;h3&gt;
&lt;p&gt;To avoid running &lt;code&gt;nvm use&lt;&#x2F;code&gt; every time you open a terminal, set a default:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; alias default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every new session will start with Node 18.17.0 active.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;essential-commands&quot;&gt;Essential Commands&lt;&#x2F;h2&gt;
&lt;p&gt;List all installed versions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The output shows installed versions and marks the active one:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       v16.20.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-&amp;gt;     v18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       v20.10.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;default -&amp;gt; 18.17.0 (-&amp;gt; v18.17.0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check what is currently active:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; current&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Run a command using a specific version without switching your session:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; exec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 16.20.2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; node app.js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is useful for one-off checks or running scripts that need a specific version while you keep working on another.&lt;&#x2F;p&gt;
&lt;p&gt;Find the binary path for a version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; which&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Output:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;Users&#x2F;username&#x2F;.nvm&#x2F;versions&#x2F;node&#x2F;v18.17.0&#x2F;bin&#x2F;node&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Uninstall a version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; uninstall&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 16.20.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Uninstalling a version also removes all globally installed packages for that version. Make a note of what you have installed globally before removing a version.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;project-specific-version-control-with-nvmrc&quot;&gt;Project-Specific Version Control with &lt;code&gt;.nvmrc&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The real productivity gain comes from locking Node versions per project. Create an &lt;code&gt;.nvmrc&lt;&#x2F;code&gt; file in your project root:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot; data-name=&quot;.nvmrc&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or generate it from the command line:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;18.17.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; .nvmrc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When you or a teammate clones the repo and runs &lt;code&gt;nvm use&lt;&#x2F;code&gt; from the project directory, NVM reads the file and switches to the correct version automatically. No version arguments needed.&lt;&#x2F;p&gt;
&lt;p&gt;This eliminates the &quot;works on my machine&quot; problem caused by different team members running different Node versions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;auto-switching-on-directory-change&quot;&gt;Auto-Switching on Directory Change&lt;&#x2F;h3&gt;
&lt;p&gt;You can go one step further and have NVM switch versions automatically whenever you &lt;code&gt;cd&lt;&#x2F;code&gt; into a directory that has an &lt;code&gt;.nvmrc&lt;&#x2F;code&gt;. Add this to your &lt;code&gt;~&#x2F;.zshrc&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot; data-name=&quot;~&#x2F;.zshrc&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;autoload&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -U&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; add-zsh-hook&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;load-nvmrc&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; [[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span&gt; .nvmrc &lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;&amp;amp;&amp;amp; -r&lt;&#x2F;span&gt;&lt;span&gt; .nvmrc ]];&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;    nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; use&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;add-zsh-hook&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; chdir load-nvmrc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After reloading your shell, entering a directory with &lt;code&gt;.nvmrc&lt;&#x2F;code&gt; triggers &lt;code&gt;nvm use&lt;&#x2F;code&gt; without any manual step.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;managing-global-packages-across-versions&quot;&gt;Managing Global Packages Across Versions&lt;&#x2F;h2&gt;
&lt;p&gt;Each Node version has its own isolated set of global packages. If you install &lt;code&gt;nodemon&lt;&#x2F;code&gt; globally on Node 18, it will not exist on Node 20.&lt;&#x2F;p&gt;
&lt;p&gt;Install a global package for the current version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;npm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; nodemon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When you upgrade to a new Node version, you can carry global packages over:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 20.10.0 --reinstall-packages-from=18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This installs Node 20.10.0 and copies all global packages from 18.17.0 to the new version.&lt;&#x2F;p&gt;
&lt;p&gt;View the global packages for your current version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;npm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -g --depth=0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;nvm-command-not-found&quot;&gt;&lt;code&gt;nvm: command not found&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The shell cannot locate NVM. The install script should have added initialization lines to your profile, but sometimes it does not. Check your &lt;code&gt;~&#x2F;.bashrc&lt;&#x2F;code&gt;, &lt;code&gt;~&#x2F;.zshrc&lt;&#x2F;code&gt;, or &lt;code&gt;~&#x2F;.profile&lt;&#x2F;code&gt; for these lines:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;export&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; NVM_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$HOME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;.nvm&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$NVM_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;nvm.sh&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ] &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; \.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$NVM_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;nvm.sh&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If they are missing, add them manually and run &lt;code&gt;source ~&#x2F;.bashrc&lt;&#x2F;code&gt; or &lt;code&gt;source ~&#x2F;.zshrc&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;slow-terminal-startup&quot;&gt;Slow Terminal Startup&lt;&#x2F;h3&gt;
&lt;p&gt;NVM loads on every shell init, which adds a small delay. You can defer that load until you first use NVM by replacing the standard init lines with this lazy-loading version:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot; data-name=&quot;~&#x2F;.zshrc&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;  unset&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; nvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C678DD;&quot;&gt;  export&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; NVM_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$HOME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;.nvm&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt; -s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$NVM_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;nvm.sh&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ] &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; \.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$NVM_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&#x2F;nvm.sh&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;  nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;font-style: italic;&quot;&gt;$@&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;NVM loads the first time you call it, not when the shell starts.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;version-not-persisting-across-terminals&quot;&gt;Version Not Persisting Across Terminals&lt;&#x2F;h3&gt;
&lt;p&gt;You have not set a default. Fix it with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;nvm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; alias default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; 18.17.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;permission-errors-on-linux&quot;&gt;Permission Errors on Linux&lt;&#x2F;h3&gt;
&lt;p&gt;Never run NVM commands with &lt;code&gt;sudo&lt;&#x2F;code&gt;. NVM is designed to run as your user, and using &lt;code&gt;sudo&lt;&#x2F;code&gt; breaks the permission model. If you are hitting permission errors, the likely cause is that &lt;code&gt;~&#x2F;.nvm&lt;&#x2F;code&gt; was created with wrong ownership. Fix it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; chown&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -R&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt; $USER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E06C75;&quot;&gt;$USER&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; ~&#x2F;.nvm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;keeping-nvm-up-to-date&quot;&gt;Keeping NVM Up to Date&lt;&#x2F;h2&gt;
&lt;p&gt;NVM does not have an &lt;code&gt;nvm update&lt;&#x2F;code&gt; command. To upgrade, re-run the install script with the new version number in the URL. Check the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nvm-sh&#x2F;nvm&#x2F;releases&quot;&gt;NVM GitHub releases&lt;&#x2F;a&gt; for the latest version, then run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -o-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;nvm-sh&#x2F;nvm&#x2F;v0.39.7&#x2F;install.sh&lt;&#x2F;span&gt;&lt;span&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt; bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Replace &lt;code&gt;v0.39.7&lt;&#x2F;code&gt; with the current release. The script is safe to re-run on an existing installation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;&#x2F;h2&gt;
&lt;p&gt;NVM reduces multi-version Node.js management to a handful of commands. The core workflow is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nvm install &amp;lt;version&amp;gt;&lt;&#x2F;code&gt; to get a version&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;nvm use &amp;lt;version&amp;gt;&lt;&#x2F;code&gt; to activate it in the current session&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;nvm alias default &amp;lt;version&amp;gt;&lt;&#x2F;code&gt; to set a permanent default&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;.nvmrc&lt;&#x2F;code&gt; files to lock versions per project&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One thing to keep in mind: global packages are version-specific. When you install a new Node version, reinstall or migrate your globals. It is a small cost for a development environment that stays predictable across projects and machines.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fix Dual Boot: Restore Ubuntu GRUB After a Windows Update</title>
        <published>2025-06-14T00:00:00+00:00</published>
        <updated>2025-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/fix-grub-dual-boot-ubuntu-windows/"/>
        <id>https://akash11.com/blog/fix-grub-dual-boot-ubuntu-windows/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/fix-grub-dual-boot-ubuntu-windows/">&lt;p&gt;You set up Ubuntu and Windows on the same machine. Everything worked. Then Windows pushed an update, and now your system boots straight into Windows. Ubuntu is gone from the menu. Maybe you saw this before it gave up:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Failed to open \EFI\UBUNTU\grubx64.efi - Not Found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Failed to load image \EFI\UBUNTU\grubx64.efi: Not Found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;start_image() returned Not Found, falling back to default loader&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Your Ubuntu installation is still on the disk. Nothing was deleted. The problem is that Windows overwrote the GRUB bootloader files in the EFI System Partition. This guide shows you how to restore them using a live Ubuntu USB drive.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;what-happened-and-why&quot;&gt;What Happened and Why&lt;&#x2F;h2&gt;
&lt;p&gt;When you boot a modern computer, the firmware reads from a special partition called the &lt;strong&gt;EFI System Partition&lt;&#x2F;strong&gt; (ESP). This FAT32 partition contains bootloader files for every operating system installed. When you installed Ubuntu, it placed GRUB&#x27;s files at &lt;code&gt;\EFI\UBUNTU\grubx64.efi&lt;&#x2F;code&gt; inside that partition.&lt;&#x2F;p&gt;
&lt;p&gt;Windows updates sometimes overwrite or reset the default EFI boot entry to point only to the Windows Boot Manager. In some cases, they delete Ubuntu&#x27;s EFI files entirely. Either way, the result is the same: GRUB is gone from the boot sequence, and Ubuntu never starts.&lt;&#x2F;p&gt;
&lt;p&gt;The fix is to boot from a live Ubuntu USB, mount your existing Ubuntu installation, and reinstall GRUB into the correct location.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-important&quot;&gt;
&lt;p&gt;This process does not touch your Ubuntu or Windows data partitions. You will not lose files. The only thing you are modifying is the bootloader in the EFI partition.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;what-you-need&quot;&gt;What You Need&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;A bootable Ubuntu USB drive (the same version or newer than your installed Ubuntu)&lt;&#x2F;li&gt;
&lt;li&gt;About 10 to 15 minutes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you do not have a live USB ready, create one using &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;etcher.balena.io&#x2F;&quot;&gt;Balena Etcher&lt;&#x2F;a&gt; or the Ubuntu Startup Disk Creator.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-1-boot-into-the-live-usb&quot;&gt;Step 1: Boot into the Live USB&lt;&#x2F;h2&gt;
&lt;p&gt;Insert the USB drive and restart your computer. As it powers on, press the boot menu key for your machine. This is usually &lt;code&gt;F12&lt;&#x2F;code&gt;, &lt;code&gt;F10&lt;&#x2F;code&gt;, &lt;code&gt;Esc&lt;&#x2F;code&gt;, or &lt;code&gt;Del&lt;&#x2F;code&gt;, depending on your motherboard manufacturer.&lt;&#x2F;p&gt;
&lt;p&gt;Select your USB drive from the boot menu. When the Ubuntu installer appears, choose &lt;strong&gt;Try Ubuntu&lt;&#x2F;strong&gt; (not &quot;Install Ubuntu&quot;). This loads a temporary Ubuntu session without touching your disk.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-2-open-a-terminal&quot;&gt;Step 2: Open a Terminal&lt;&#x2F;h2&gt;
&lt;p&gt;Once the desktop loads, press &lt;code&gt;Ctrl + Alt + T&lt;&#x2F;code&gt; to open a terminal. All the following commands run here.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-3-find-your-partitions&quot;&gt;Step 3: Find Your Partitions&lt;&#x2F;h2&gt;
&lt;p&gt;You need to identify two partitions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Your &lt;strong&gt;Ubuntu root partition&lt;&#x2F;strong&gt; (the one formatted as ext4 that contains your Ubuntu installation)&lt;&#x2F;li&gt;
&lt;li&gt;Your &lt;strong&gt;EFI System Partition&lt;&#x2F;strong&gt; (a small FAT32 partition, usually 100 to 512 MB)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; fdisk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The output lists every disk and partition. Look for something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Device             Start       End   Sectors   Size Type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;nvme0n1p1      2048    534527    532480   260M EFI System&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;nvme0n1p2    534528    796671    262144   128M Microsoft reserved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;nvme0n1p3    796672 209559551 208762880  99.6G Microsoft basic data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;nvme0n1p4 209559552 500117503 290557952 138.6G Linux filesystem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this example, &lt;code&gt;nvme0n1p1&lt;&#x2F;code&gt; is the EFI partition and &lt;code&gt;nvme0n1p4&lt;&#x2F;code&gt; is the Ubuntu root partition. Your partition names will differ. Note them down before continuing.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
&lt;p&gt;If you have an older SATA drive instead of NVMe, your partitions will be named like &lt;code&gt;&#x2F;dev&#x2F;sda1&lt;&#x2F;code&gt;, &lt;code&gt;&#x2F;dev&#x2F;sda2&lt;&#x2F;code&gt;, and so on. The process is identical.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-4-mount-the-ubuntu-partition&quot;&gt;Step 4: Mount the Ubuntu Partition&lt;&#x2F;h2&gt;
&lt;p&gt;Create a mount point and mount your Ubuntu root partition:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;mnt&#x2F;ubuntu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; mount &#x2F;dev&#x2F;nvme0n1p4 &#x2F;mnt&#x2F;ubuntu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Replace &lt;code&gt;&#x2F;dev&#x2F;nvme0n1p4&lt;&#x2F;code&gt; with your actual Ubuntu partition.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-5-mount-the-efi-partition&quot;&gt;Step 5: Mount the EFI Partition&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;mnt&#x2F;ubuntu&#x2F;boot&#x2F;efi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; mount &#x2F;dev&#x2F;nvme0n1p1 &#x2F;mnt&#x2F;ubuntu&#x2F;boot&#x2F;efi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Replace &lt;code&gt;&#x2F;dev&#x2F;nvme0n1p1&lt;&#x2F;code&gt; with your actual EFI partition.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-6-mount-the-required-system-directories&quot;&gt;Step 6: Mount the Required System Directories&lt;&#x2F;h2&gt;
&lt;p&gt;GRUB needs access to device nodes, process information, and kernel interfaces during reinstallation. These three bind mounts provide that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --bind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;dev  &#x2F;mnt&#x2F;ubuntu&#x2F;dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --bind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;proc &#x2F;mnt&#x2F;ubuntu&#x2F;proc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --bind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;sys  &#x2F;mnt&#x2F;ubuntu&#x2F;sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-7-enter-your-installed-ubuntu-system&quot;&gt;Step 7: Enter Your Installed Ubuntu System&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;chroot&lt;&#x2F;code&gt; switches your active root directory to the mounted Ubuntu installation. After this command, you are running inside your real Ubuntu system, not the live USB:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; chroot &#x2F;mnt&#x2F;ubuntu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Your terminal prompt will change. Commands you run now affect your installed system, not the live environment.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-8-reinstall-grub&quot;&gt;Step 8: Reinstall GRUB&lt;&#x2F;h2&gt;
&lt;p&gt;Run &lt;code&gt;grub-install&lt;&#x2F;code&gt; targeting the &lt;strong&gt;disk&lt;&#x2F;strong&gt;, not a partition. Then update the GRUB configuration:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;grub-install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; &#x2F;dev&#x2F;nvme0n1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;update-grub&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Replace &lt;code&gt;&#x2F;dev&#x2F;nvme0n1&lt;&#x2F;code&gt; with your actual disk identifier. If you are unsure which one to use, run &lt;code&gt;lsblk&lt;&#x2F;code&gt; and look for the root device that contains your partitions. It will not have a number at the end.&lt;&#x2F;p&gt;
&lt;p&gt;You should see output similar to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Installing for x86_64-efi platform.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Installation finished. No error reported.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Generating grub configuration file ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found linux image: &#x2F;boot&#x2F;vmlinuz-6.8.0-60-generic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found Windows Boot Manager on &#x2F;dev&#x2F;nvme0n1p1@&#x2F;EFI&#x2F;Microsoft&#x2F;Boot&#x2F;bootmgfw.efi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The line confirming Windows Boot Manager was found is important. It means GRUB will include Windows in the boot menu automatically.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;If &lt;code&gt;grub-install&lt;&#x2F;code&gt; reports an error about not finding an EFI directory or missing packages, make sure the EFI partition is correctly mounted at &lt;code&gt;&#x2F;mnt&#x2F;ubuntu&#x2F;boot&#x2F;efi&lt;&#x2F;code&gt; and try again. Do not skip to &lt;code&gt;update-grub&lt;&#x2F;code&gt; alone as that does not reinstall the EFI files.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-9-exit-and-unmount&quot;&gt;Step 9: Exit and Unmount&lt;&#x2F;h2&gt;
&lt;p&gt;Exit the chroot environment:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #56B6C2;&quot;&gt;exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now unmount everything in reverse order:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; umount &#x2F;mnt&#x2F;ubuntu&#x2F;dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; umount &#x2F;mnt&#x2F;ubuntu&#x2F;proc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; umount &#x2F;mnt&#x2F;ubuntu&#x2F;sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; umount &#x2F;mnt&#x2F;ubuntu&#x2F;boot&#x2F;efi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #495162;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; umount &#x2F;mnt&#x2F;ubuntu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;step-10-reboot&quot;&gt;Step 10: Reboot&lt;&#x2F;h2&gt;
&lt;p&gt;Remove the USB drive and restart:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; reboot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Your system should now show the GRUB menu with both Ubuntu and Windows listed. Select Ubuntu to confirm it boots correctly.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;if-the-problem-comes-back-after-the-next-windows-update&quot;&gt;If the Problem Comes Back After the Next Windows Update&lt;&#x2F;h2&gt;
&lt;p&gt;Windows has a habit of resetting the EFI boot order after major updates. To reduce the chance of this happening again, you can set GRUB as the default EFI boot entry at the firmware level.&lt;&#x2F;p&gt;
&lt;p&gt;After booting back into Ubuntu normally, run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; efibootmgr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; -v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This lists all EFI boot entries. Look for the entry labelled &lt;code&gt;ubuntu&lt;&#x2F;code&gt; or &lt;code&gt;GRUB&lt;&#x2F;code&gt; and note its boot number (for example, &lt;code&gt;Boot0003&lt;&#x2F;code&gt;). Then set it as the default:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #ABB2BF; background-color: #282C34;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #61AFEF;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; efibootmgr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D19A66;&quot;&gt; --bootorder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #98C379;&quot;&gt; 0003,0001,0000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Put the GRUB entry number first in the list. This tells the firmware to always try GRUB before the Windows Boot Manager, making it harder for Windows updates to take over.&lt;&#x2F;p&gt;
&lt;p&gt;That said, some machines with aggressive firmware will still reset this. If you dual boot regularly, it is worth checking the boot order after every major Windows update.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Smart Contract Security Research: A Curated Resource List</title>
        <published>2025-06-03T00:00:00+00:00</published>
        <updated>2025-06-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            Akash Vaghela
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/blog/web3-smart-contract-security-resources/"/>
        <id>https://akash11.com/blog/web3-smart-contract-security-resources/</id>
        
        <content type="html" xml:base="https://akash11.com/blog/web3-smart-contract-security-resources/">&lt;p&gt;Smart contract security is a demanding field. You need to understand Solidity, the EVM, DeFi protocols, cryptographic primitives, and how attackers think — all at once.&lt;&#x2F;p&gt;
&lt;p&gt;This post collects the resources worth your time. Each section covers a distinct area of knowledge. Work through them in order if you are starting out, or jump to the section you need.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solidity-and-the-evm&quot;&gt;Solidity and the EVM&lt;&#x2F;h2&gt;
&lt;p&gt;Before auditing contracts, you need to read and write Solidity well. These resources cover the language and the execution environment beneath it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Official documentation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.soliditylang.org&#x2F;en&#x2F;v0.8.30&#x2F;&quot;&gt;Solidity Docs&lt;&#x2F;a&gt; — the authoritative reference for the language&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;solidity-by-example.org&#x2F;&quot;&gt;Solidity by Example&lt;&#x2F;a&gt; — short, focused examples of common patterns&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;EVM internals&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.decipherclub.com&#x2F;ethereum-virtual-machine-article-series&#x2F;&quot;&gt;Ethereum Virtual Machine by Zaryab&lt;&#x2F;a&gt; — a readable series on how the EVM actually executes code&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Secureum series&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Secureum substack is one of the most concentrated sources of Ethereum and Solidity knowledge available. Read these in order:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;ethereum-101&quot;&gt;Ethereum 101&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;solidity-101&quot;&gt;Solidity 101&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;solidity-201&quot;&gt;Solidity 201&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;shanzson&#x2F;Smart-Contract-Auditor-Tools-and-Techniques?tab=readme-ov-file#ethereum-blogs-to-deep-dive&quot;&gt;Ethereum blog deep dives&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Quick reference&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;manojpramesh&#x2F;solidity-cheatsheet&quot;&gt;Solidity Cheatsheet&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;topmonks.github.io&#x2F;solidity_quick_ref&#x2F;&quot;&gt;Solidity Quick Reference&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;foundry&quot;&gt;Foundry&lt;&#x2F;h2&gt;
&lt;p&gt;Foundry is the standard toolkit for writing tests, running forks, and building proof-of-concept exploits in Solidity. If you are not using it already, start now.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;book.getfoundry.sh&#x2F;&quot;&gt;Foundry Book&lt;&#x2F;a&gt; — complete documentation for the toolchain&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;token-standards-and-eips&quot;&gt;Token Standards and EIPs&lt;&#x2F;h2&gt;
&lt;p&gt;Auditors spend a lot of time reviewing token contracts. Knowing the standards and their edge cases is not optional.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ethereum.org&#x2F;en&#x2F;developers&#x2F;docs&#x2F;standards&#x2F;tokens&#x2F;&quot;&gt;Token Standards: ERC-20, 721, 777, 1155, 4626&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2981&quot;&gt;ERC-2981: NFT Royalty Standard&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abarbatei&#x2F;weird-erc721&quot;&gt;Weird ERC-721 Tokens&lt;&#x2F;a&gt; — a collection of non-standard ERC-721 implementations that break naive assumptions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;razzorsec&#x2F;AuditorsRoadmap?tab=readme-ov-file#16-important-ethereum-improvement-proposals-eips&quot;&gt;Important EIPs for Auditors&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;proxy-patterns-and-upgradeable-contracts&quot;&gt;Proxy Patterns and Upgradeable Contracts&lt;&#x2F;h2&gt;
&lt;p&gt;Proxy contracts are a common source of vulnerabilities. The different patterns each carry different risks.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ethereum-blockchain-developer.com&#x2F;110-upgrade-smart-contracts&#x2F;00-project&#x2F;&quot;&gt;Proxy Patterns Overview: EIPs 897, 1822, 1967, 1538, 2535&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;electisec&#x2F;Solidity-Proxy-Playground&quot;&gt;Solidity Proxy Playground&lt;&#x2F;a&gt; — both vulnerable and fixed implementations to study side by side&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security-best-practices-and-checklists&quot;&gt;Security Best Practices and Checklists&lt;&#x2F;h2&gt;
&lt;p&gt;These resources cover what to look for during a review and how to structure your thinking.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;security-pitfalls-and-best-practices-101&quot;&gt;Security Pitfalls and Best Practices 101&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;security-pitfalls-and-best-practices-201&quot;&gt;Security Pitfalls and Best Practices 201&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.soliditylang.org&#x2F;en&#x2F;latest&#x2F;security-considerations.html&quot;&gt;Solidity Security Considerations&lt;&#x2F;a&gt; — official guidance from the Solidity team&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;securing&#x2F;SCSVS&#x2F;tree&#x2F;master&quot;&gt;Smart Contract Security Verification Standard (SCSVS)&lt;&#x2F;a&gt; — a structured checklist for audits&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dragonfly-xyz&#x2F;useful-solidity-patterns&quot;&gt;Useful Solidity Patterns&lt;&#x2F;a&gt; — patterns that help avoid common mistakes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;transmissions11&#x2F;solcurity&quot;&gt;The Solcurity Standard&lt;&#x2F;a&gt; — a practical security checklist from the community&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Decurity&#x2F;semgrep-smart-contracts&quot;&gt;Semgrep Rules for Smart Contracts&lt;&#x2F;a&gt; — static analysis rules you can run on codebases&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OpenCoreCH&#x2F;smart-contract-auditing-heuristics&quot;&gt;Smart Contract Auditing Heuristics&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;defi-knowledge&quot;&gt;DeFi Knowledge&lt;&#x2F;h2&gt;
&lt;p&gt;Most audit targets are DeFi protocols. Understanding how they work — AMMs, lending markets, derivatives, vaults — is a prerequisite for finding meaningful bugs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Finance foundations&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.khanacademy.org&#x2F;economics-finance-domain&#x2F;core-finance&#x2F;derivative-securities&quot;&gt;Khan Academy: Derivatives and Other Securities&lt;&#x2F;a&gt; — start here if you are not familiar with how financial instruments work&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;DeFi overviews&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OffcierCia&#x2F;DeFi-Developer-Road-Map&#x2F;tree&#x2F;main&quot;&gt;DeFi Developer Roadmap&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;teachyourselfcrypto.com&#x2F;#ftoc-module-4-decentralized-finance-defi&quot;&gt;Teach Yourself Crypto: DeFi Module&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=pWGLtjG-F5c&amp;amp;list=PLjrTIwaNiTwn39tg3sR_bPBWGHoznv47D&quot;&gt;Finematics DeFi Playlist&lt;&#x2F;a&gt; — visual explainers for major DeFi protocols&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=qB2Ulx201wY&amp;amp;list=PLO5VPQH6OWdX-Rh7RonjZhOd9pb9zOnHW&quot;&gt;Smart Contract Programmer DeFi Playlist&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;razzorsec&#x2F;AuditorsRoadmap?tab=readme-ov-file#11-defi-deep-dive&quot;&gt;RazzorSec DeFi Deep Dive&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;vulnerabilities-and-attack-vectors&quot;&gt;Vulnerabilities and Attack Vectors&lt;&#x2F;h2&gt;
&lt;p&gt;This is the core of security research. Study these to understand what attackers exploit and how.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Secureum&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;audit-techniques-and-tools-101&quot;&gt;Audit Techniques and Tools 101&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;audit-findings-101&quot;&gt;Audit Findings 101&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;audit-findings-201&quot;&gt;Audit Findings 201&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Vulnerability databases and lists&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sigp&#x2F;solidity-security-blog&quot;&gt;Solidity Security Blog by sigp&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kadenzipfel&#x2F;smart-contract-vulnerabilities&quot;&gt;Smart Contract Vulnerabilities&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;swcregistry.io&#x2F;&quot;&gt;Smart Contract Weakness Classification (SWC Registry)&lt;&#x2F;a&gt; — structured classification of known weaknesses&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;harendra-shakya&#x2F;smart-contract-attack-vectors&quot;&gt;Smart Contract Attack Vectors&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;SunWeb3Sec&#x2F;DeFiVulnLabs&#x2F;tree&#x2F;main&quot;&gt;DeFiVulnLabs by SunWeb3Sec&lt;&#x2F;a&gt; — live, runnable PoC exploits for known vulnerabilities&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;immunefi-team&#x2F;Web3-Security-Library#vulnerabilities&quot;&gt;Immunefi Vulnerability Library&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;QuillHash collections&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Quillhash&#x2F;DeFi-Attack-Vectors&quot;&gt;DeFi Attack Vectors&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Quillhash&#x2F;Solidity-Attack-Vectors&quot;&gt;Solidity Attack Vectors&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Additional references&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;shanzson&#x2F;Smart-Contract-Auditor-Tools-and-Techniques?tab=readme-ov-file#defi-focused-security-resources&quot;&gt;DeFi-Focused Security Resources&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xJuancito&#x2F;multichain-auditor&quot;&gt;Multichain Auditor: Cross-Chain Vulnerabilities and Checklist&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;audit-reports&quot;&gt;Audit Reports&lt;&#x2F;h2&gt;
&lt;p&gt;Reading past audit reports is one of the most effective ways to develop an eye for bugs. You see how real auditors reason, what they flag, and how they write findings.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Contest platforms&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;code4rena.com&#x2F;reports&quot;&gt;Code4rena Reports&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sherlock-protocol&#x2F;sherlock-reports&quot;&gt;Sherlock Reports&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;theauditorbook.com&#x2F;&quot;&gt;The Auditor Book&lt;&#x2F;a&gt; — aggregated Sherlock and Code4rena findings&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;audit-hero.com&#x2F;search-findings&quot;&gt;Audit Hero&lt;&#x2F;a&gt; — search Code4rena and Sherlock findings together&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;solodit.cyfrin.io&#x2F;?i=HIGH%2CMEDIUM&quot;&gt;Solodit by Cyfrin&lt;&#x2F;a&gt; — filtered view of high and medium findings across contests&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Bug bounty writeups&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sayan011&#x2F;Immunefi-bug-bounty-writeups-list&quot;&gt;Immunefi Bug Bounty Writeups&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Security firms&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;consensys.io&#x2F;diligence&#x2F;audits&#x2F;&quot;&gt;Consensys Diligence&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;trailofbits&#x2F;publications#ethereumevm&quot;&gt;Trail of Bits (Ethereum&#x2F;EVM)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.openzeppelin.com&#x2F;tag&#x2F;security-audits&quot;&gt;OpenZeppelin Security Audits&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spearbit&#x2F;portfolio&quot;&gt;Spearbit Portfolio&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Quillhash&#x2F;QuillAudit_Reports&quot;&gt;QuillHash Audit Reports&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Solo auditor portfolios&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These are worth reading to see how individual auditors present their work:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nullity00&#x2F;zk-security-reviews&quot;&gt;nullity00 (ZK security reviews)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nevillehuang&#x2F;Portfolio&quot;&gt;NevilleHuang&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zobront&#x2F;audits&quot;&gt;Zobront Audits&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Lists and directories&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xNazgul&#x2F;Blockchain-Security-Audit-List&quot;&gt;Blockchain Security Audit List&lt;&#x2F;a&gt; — firms and solo auditors&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;cwhinfrey&#x2F;9fd1bbc31bbcff08fca242b90c7f875d&quot;&gt;Bridge Hack List&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;secureum-safu-series&quot;&gt;Secureum SAFU Series&lt;&#x2F;h3&gt;
&lt;p&gt;A focused set of posts analyzing the security of specific DeFi protocols:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;eth2-security-overview-secureum-1&quot;&gt;Eth2 Security Overview&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;smart-contract-security-resources&quot;&gt;Smart Contract Security Resources&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;making-defi-safu-secureum-3&quot;&gt;Making DeFi SAFU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;making-hermez-safu-secureum-4&quot;&gt;Making Hermez SAFU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;making-cover-safu-secureum-5&quot;&gt;Making Cover SAFU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;smart-contract-security-101-secureum&quot;&gt;Making Opyn SAFU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;making-defi-safu-secureum-3&quot;&gt;Smart Contract Security 101&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;making-primitive-safu-secureum-8&quot;&gt;Making Primitive SAFU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;secureum.substack.com&#x2F;p&#x2F;making-alpha-safu-secureum-9&quot;&gt;Making Alpha SAFU&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ctfs-and-hands-on-practice&quot;&gt;CTFs and Hands-On Practice&lt;&#x2F;h2&gt;
&lt;p&gt;Reading about vulnerabilities is not enough. You need to exploit them yourself. These CTFs give you practice in a structured environment.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ethernaut.openzeppelin.com&#x2F;&quot;&gt;Ethernaut&lt;&#x2F;a&gt; — the classic starting point for smart contract security challenges&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;capturetheether.com&#x2F;&quot;&gt;Capture the Ether&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.damnvulnerabledefi.xyz&#x2F;&quot;&gt;Damn Vulnerable DeFi&lt;&#x2F;a&gt; — DeFi-specific challenges, progressively harder&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ctf.paradigm.xyz&#x2F;&quot;&gt;Paradigm CTF&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
&lt;p&gt;After completing a challenge, read other players&#x27; writeups. The same vulnerability can often be exploited in multiple ways, and seeing different approaches sharpens your thinking.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;contest-practice&quot;&gt;Contest Practice&lt;&#x2F;h2&gt;
&lt;p&gt;Once you have finished the CTFs, first-flight contests are a low-stakes way to practice writing findings on real (if simpler) codebases.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codehawks.cyfrin.io&#x2F;first-flights?ended=true&amp;amp;judging=true&amp;amp;live=true&amp;amp;sort=endDate&amp;amp;upcoming=true&quot;&gt;CodeHawks First Flights&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;writing-proof-of-concept-exploits&quot;&gt;Writing Proof of Concept Exploits&lt;&#x2F;h2&gt;
&lt;p&gt;A finding without a working PoC is weak. These resources cover how to build them properly.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;immunefi-team&#x2F;Web3-Security-Library&#x2F;blob&#x2F;main&#x2F;Check%20This%20Out&#x2F;README.md#poc-like-a-pro&quot;&gt;PoC Like a Pro&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;shanzson&#x2F;Smart-Contract-Auditor-Tools-and-Techniques?tab=readme-ov-file#pocs&quot;&gt;Coinspect and DeFi Hack Labs PoCs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;postmortems-and-bug-fix-analysis&quot;&gt;Postmortems and Bug Fix Analysis&lt;&#x2F;h2&gt;
&lt;p&gt;Studying how protocols responded to real exploits teaches you what auditors missed and why. This is underrated as a learning method.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;razzorsec&#x2F;AuditorsRoadmap?tab=readme-ov-file#13-postmortems--bugfixes&quot;&gt;Postmortem Writeups&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sirhashalot&#x2F;SCV-List?tab=readme-ov-file&quot;&gt;SCV-List&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;where-to-start&quot;&gt;Where to Start&lt;&#x2F;h2&gt;
&lt;p&gt;If you are new to smart contract security, a reasonable progression is:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Learn Solidity basics using Solidity by Example and the Secureum 101 posts&lt;&#x2F;li&gt;
&lt;li&gt;Understand the EVM at a basic level before going deeper&lt;&#x2F;li&gt;
&lt;li&gt;Work through Ethernaut, then Damn Vulnerable DeFi&lt;&#x2F;li&gt;
&lt;li&gt;Read 10 to 20 high-severity findings on Solodit and understand each one&lt;&#x2F;li&gt;
&lt;li&gt;Participate in a CodeHawks First Flight contest&lt;&#x2F;li&gt;
&lt;li&gt;Expand your DeFi knowledge in parallel with your security knowledge&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The two skills reinforce each other. The better you understand how a protocol is supposed to work, the easier it is to see where it breaks.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>X</title>
        <published>2025-01-01T00:00:00+00:00</published>
        <updated>2025-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/email/"/>
        <id>https://akash11.com/email/</id>
        
        <content type="html" xml:base="https://akash11.com/email/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>X</title>
        <published>2025-01-01T00:00:00+00:00</published>
        <updated>2025-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/github/"/>
        <id>https://akash11.com/github/</id>
        
        <content type="html" xml:base="https://akash11.com/github/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>X</title>
        <published>2025-01-01T00:00:00+00:00</published>
        <updated>2025-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/linkedin/"/>
        <id>https://akash11.com/linkedin/</id>
        
        <content type="html" xml:base="https://akash11.com/linkedin/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Resume</title>
        <published>2025-01-01T00:00:00+00:00</published>
        <updated>2025-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/resume/"/>
        <id>https://akash11.com/resume/</id>
        
        <content type="html" xml:base="https://akash11.com/resume/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Telegram</title>
        <published>2025-01-01T00:00:00+00:00</published>
        <updated>2025-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/telegram/"/>
        <id>https://akash11.com/telegram/</id>
        
        <content type="html" xml:base="https://akash11.com/telegram/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>X</title>
        <published>2025-01-01T00:00:00+00:00</published>
        <updated>2025-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/x/"/>
        <id>https://akash11.com/x/</id>
        
        <content type="html" xml:base="https://akash11.com/x/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>About</title>
        <published>2023-01-08T00:00:00+00:00</published>
        <updated>2025-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/about/"/>
        <id>https://akash11.com/about/</id>
        
        <content type="html" xml:base="https://akash11.com/about/">&lt;p&gt;I&#x27;m Akash Vaghela, a full-stack engineer based in Jamnagar, Gujarat.&lt;&#x2F;p&gt;
&lt;p&gt;I started with a Chemical Engineering degree, a strong academic record, and a final-year project that received funding from the Gujarat government&#x27;s Student Startup and Innovation Policy (SSIP). But I realized early that it wasn&#x27;t the direction I wanted my career to go. So I trusted that instinct, switched paths after graduation, and joined Masai School to learn software development.&lt;&#x2F;p&gt;
&lt;p&gt;That decision led to five years of building things across startups and enterprises. I started at Capgemini, working with a global team on internal tools for P&amp;amp;G. Then came a run of startup roles, founding engineer stints, zero-to-one builds, direct customer interaction, each one pushing me into unfamiliar territory and making me a better engineer for it. Along the way I&#x27;ve tripled product activation rates with AI-powered onboarding, shipped real-time WebSocket dashboards, and independently launched two monetized products that are live today.&lt;&#x2F;p&gt;
&lt;p&gt;Most of that work has been in the MERN stack. But I&#x27;m now deliberately expanding into Rust and the Solana ecosystem. It&#x27;s early days. I&#x27;m learning, getting involved in communities, and building toward a longer-term interest in systems programming and on-chain development. The transition feels right, for the same reason the original career switch did.&lt;&#x2F;p&gt;
&lt;p&gt;Outside of work, I read a lot. Tech, fiction, philosophy, no particular loyalty to genre. A few books that have genuinely shaped how I think: &lt;strong&gt;&lt;em&gt;Siddhartha&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; by Hermann Hesse, &lt;strong&gt;&lt;em&gt;Tuesdays with Morrie&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; by Mitch Albom, and &lt;strong&gt;&lt;em&gt;Animal Farm&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; by George Orwell. I also watch a lot of films, particularly science fiction, and find myself paying attention to the craft, the shot selection, the sound design, how a story is constructed.&lt;&#x2F;p&gt;
&lt;p&gt;Feel free to reach out on &lt;a href=&quot;&#x2F;linkedin&quot;&gt;LinkedIn&lt;&#x2F;a&gt; or &lt;a href=&quot;&#x2F;x&quot;&gt;X&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Certifications</title>
        <published>2023-01-08T00:00:00+00:00</published>
        <updated>2023-01-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/certifications/"/>
        <id>https://akash11.com/certifications/</id>
        
        <content type="html" xml:base="https://akash11.com/certifications/">&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Certification&lt;&#x2F;th&gt;&lt;th&gt;Issuer&lt;&#x2F;th&gt;&lt;th&gt;Year&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;specialization&#x2F;certificate&#x2F;5VFF9SE3B5GC&quot;&gt;Blockchain Specialization&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;University at Buffalo&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;certificate&#x2F;5V6TT9R9R9VD&quot;&gt;Decentralized Applications (Dapps)&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;University at Buffalo&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;certificate&#x2F;D5YAQW93HZVJ&quot;&gt;Blockchain Platforms&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;University at Buffalo&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;certificate&#x2F;QZTE4GTVAR7E&quot;&gt;Smart Contracts&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;University at Buffalo&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;certificate&#x2F;5F88UB8MMKUF&quot;&gt;Blockchain Basics&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;University at Buffalo&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.udemy.com&#x2F;certificate&#x2F;UC-a18dbb93-6296-41a7-87fc-5d7625ff9a93&#x2F;&quot;&gt;Modern JavaScript for React JS - ES6&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Udemy&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codedamn.com&#x2F;certificate&#x2F;verify&#x2F;a8278102913e250a5aca570d1a0e755382788f54&quot;&gt;CI&#x2F;CD With GitHub Actions&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Codedamn&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;certificate&#x2F;9EN2UE5V9PJK&quot;&gt;Version Control with Git&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Atlassian University&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.udemy.com&#x2F;certificate&#x2F;UC-d67a13cb-354c-406e-8ea3-a6f1072917bf&#x2F;&quot;&gt;Git and GitHub from scratch&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Udemy&lt;&#x2F;td&gt;&lt;td&gt;2022&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.credly.com&#x2F;badges&#x2F;f3c42bd4-2320-42b3-b7ad-52b02a29e087&quot;&gt;AWS Certified Developer – Associate&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Amazon Web Services&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;specialization&#x2F;certificate&#x2F;XAL89RHX2A58&quot;&gt;Cloud Application Development Foundations&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;IBM&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.credly.com&#x2F;badges&#x2F;c8e6e53d-fc1a-4c2a-a27f-ec4779e24015&quot;&gt;Developing Cloud Apps with Node.js and React&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;IBM&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.credly.com&#x2F;badges&#x2F;0e4a51cc-75f1-480a-b82d-11bf95207bd0&quot;&gt;Developing Cloud Native Applications&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;IBM&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.credly.com&#x2F;badges&#x2F;f31760e4-4bcb-4779-838f-acd4954c3e7c&quot;&gt;Web Development with HTML, CSS, JavaScript Essentials&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;IBM&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.credly.com&#x2F;badges&#x2F;d5ffc5f6-4402-48fe-87cc-8ff1bf0bbccf&quot;&gt;Introduction to Cloud Computing&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;IBM&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.coursera.org&#x2F;account&#x2F;accomplishments&#x2F;certificate&#x2F;ANYBFGN4235L&quot;&gt;Agile Software Development&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;University of Minnesota&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.udemy.com&#x2F;certificate&#x2F;UC-767bbec9-4033-4a30-9afd-3297faaa7e2d&#x2F;&quot;&gt;JavaScript - Basics to Advanced&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;Udemy&lt;&#x2F;td&gt;&lt;td&gt;2021&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Work</title>
        <published>2023-01-08T00:00:00+00:00</published>
        <updated>2025-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://akash11.com/work/"/>
        <id>https://akash11.com/work/</id>
        
        <content type="html" xml:base="https://akash11.com/work/">&lt;h2 id=&quot;independent-developer&quot;&gt;Independent Developer&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Full Stack Engineer&lt;&#x2F;strong&gt; · Mar 2025 – Present · Ahmedabad, India&lt;&#x2F;p&gt;
&lt;p&gt;Building and shipping my own products.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;viralvision.akash11.com&quot;&gt;ViralVision&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; — AI image platform for thumbnail generation, upscaling, and character-consistent editing. Integrated the Nano Banana 2 API, built JWT auth and a credit billing system from scratch.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;chromewebstore.google.com&#x2F;detail&#x2F;contentcurator&#x2F;cohcdmigcodfchfbjaangdfnlnfkkeim&quot;&gt;ContentCurator&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; — Chrome extension for YouTube analytics. Features channel and video tracking, bookmarks, group management, CSV export, and MongoDB-backed cloud sync.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;indecab&quot;&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;indecab.com&quot;&gt;Indecab&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Full Stack Engineer&lt;&#x2F;strong&gt; · Jun 2024 – Mar 2025 · Mumbai, India (Remote)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reduced legacy code issues by 40% by migrating multiple Meteor modules to the latest version, improving reliability and cutting new developer onboarding time.&lt;&#x2F;li&gt;
&lt;li&gt;Built a Help Center CMS with modular React components, replacing ad-hoc documentation and giving the support team a proper content management workflow.&lt;&#x2F;li&gt;
&lt;li&gt;Handled Sentry error investigations, implemented bug fixes, and improved error handling across the codebase.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;visilean&quot;&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;visilean.com&quot;&gt;Visilean&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;UI Developer&lt;&#x2F;strong&gt; · Feb 2024 – May 2024 · Ahmedabad, India (Hybrid)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Revamped the Takt Visualizer dashboard for full responsiveness across desktop, tablet, and mobile, improving usability for field-based construction planning teams.&lt;&#x2F;li&gt;
&lt;li&gt;Integrated WebSocket-based real-time data updates, increasing dashboard refresh efficiency by 50%.&lt;&#x2F;li&gt;
&lt;li&gt;Optimized API and WebSocket responses to improve page speed and navigation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;salesrobot&quot;&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;salesrobot.co&quot;&gt;SalesRobot&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Full Stack Engineer&lt;&#x2F;strong&gt; · Sep 2022 – Jan 2024 · New Delhi, India (Remote)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Built SalesGPT, an AI-powered onboarding chatbot that tripled product activation rates from 11% to 35% by guiding new users through core features contextually.&lt;&#x2F;li&gt;
&lt;li&gt;Reduced time-to-feature access by 60% by redesigning key user flows and consolidating high-usage tools into a unified interface.&lt;&#x2F;li&gt;
&lt;li&gt;Developed the LeadZilla Chrome extension UI and integrated credit usage features.&lt;&#x2F;li&gt;
&lt;li&gt;Used OpenAI APIs to generate LinkedIn posts, comments, and icebreaker lines for outbound automation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;capgemini&quot;&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;capgemini.com&quot;&gt;Capgemini&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Software Engineer&lt;&#x2F;strong&gt; · Jun 2021 – Sep 2022 · Bangalore, India (Hybrid)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Built a reusable React component library (calendar, tooltips, map markers) for P&amp;amp;G&#x27;s internal enterprise tools, adopted across multiple modules.&lt;&#x2F;li&gt;
&lt;li&gt;Migrated the FullCalendar library to the latest version and integrated Google Maps with React for product location tracking.&lt;&#x2F;li&gt;
&lt;li&gt;Delivered data visualization and workflow enhancements in direct collaboration with P&amp;amp;G&#x27;s internal stakeholders.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
