<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>aṇuha</title>
        <link>https://paragraph.com/@anuha</link>
        <description>Advanced Solidity | Gas Golfing | Yul | EVM | Audit | Zero Knowledge Proofs | Puzzles</description>
        <lastBuildDate>Fri, 03 Apr 2026 17:50:39 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>aṇuha</title>
            <url>https://storage.googleapis.com/papyrus_images/ab6445c7901799917a18f9f5febde750d77297d2964a3cf0bb405dbab96c0d93.png</url>
            <link>https://paragraph.com/@anuha</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Ethereum Yellow Paper Illustrated #1]]></title>
            <link>https://paragraph.com/@anuha/ethereum-yellow-paper-illustrated-1</link>
            <guid>wh8Qej1XARwvSe2W6V1a</guid>
            <pubDate>Tue, 16 May 2023 19:17:40 GMT</pubDate>
            <description><![CDATA[As against BITCOIN, Ethereum clients can be coded in any language and many already exist. This is so because of the Yellow Paper. It is a specification. Initially, like many developers, I skipped the yellow paper and read the beige paper only to skip the math and equations. This is an attempt to decode the mathematical equations in the Ethereum Yellow Paper and understand them deeper. Importantly keeping it simple. It only gets interesting as we see it one by one.Ethereum State MachineBlock L...]]></description>
            <content:encoded><![CDATA[<p>As against <code>BITCOIN</code>, Ethereum clients can be coded in any language and many already exist. This is so because of the Yellow Paper. It is a specification. Initially, like many developers, I skipped the yellow paper and read the beige paper only to skip the math and equations. This is an attempt to decode the mathematical equations in the Ethereum Yellow Paper and understand them deeper. Importantly keeping it simple.</p><p>It only gets interesting as we see it one by one.</p><h2 id="h-ethereum-state-machine" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Ethereum State Machine</h2><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/c42a7b29c0ab8d6aa1b6e67ec89df6ecaba7baf953597ae97e075196be0b5f7e.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6f80891821f7b21db641a333e517d7fb8698e0a2f7e041c173db82caeeffa6aa.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-block-level-state-transition" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Block Level State Transition</h2><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/aef0d36a7a6f940814be41cc2a9fbe9c0f8745ed6ed6329251588c4624b43518.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/de02730f6a0196ed6b2c68869d03dea4106f3f249dc20331e662a7eb72cdd374.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Where</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/7d19867e655535060b1e9a2034105b53fbfa6a751492c05f20705d7d5ae76b5a.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/0a00f670d2b574e01caa5be6cb3937244c054ee0807821f02515975bf68eb52d.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>A FINALIZED_BLOCK_TRANISTION is a collective of a number of valid transaction level STATE_TRANSITIONS.</p>]]></content:encoded>
            <author>anuha@newsletter.paragraph.com (aṇuha)</author>
        </item>
        <item>
            <title><![CDATA[Gas Golfing #3: Zero vs NonZero Storage Values]]></title>
            <link>https://paragraph.com/@anuha/gas-golfing-3-zero-vs-nonzero-storage-values</link>
            <guid>UsqTZ4xq2FIePGtc4WAn</guid>
            <pubDate>Fri, 12 May 2023 12:31:18 GMT</pubDate>
            <description><![CDATA[This is a continuation of the previous two articles on gas optimization. While it does not matter and one can start from here. There are some references to previous articles. In Gas Golfing #1, We visited the ReentrancyGuard.sol from OpenZeppelin and discussed why a uint256 variable is used to mark the entry and exit of functions. They could have in fact used a bool or a uint8 . One of the reasons was covered in the article. We will deep dive into major reasoning in this section. Beginning wi...]]></description>
            <content:encoded><![CDATA[<p>This is a continuation of the previous two articles on gas optimization. While it does not matter and one can start from here. There are some references to previous articles.</p><p>In Gas Golfing #1, We visited the ReentrancyGuard.sol from OpenZeppelin and discussed why a <code>uint256</code> variable is used to mark the entry and exit of functions. They could have in fact used a <code>bool</code> or a <code>uint8</code> . One of the reasons was covered in the article. We will deep dive into major reasoning in this section.</p><p>Beginning with the ReentrancyGaurd from OpenZeppelin. It is below here.</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;
/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * &lt;https://blog.openzeppelin.com/reentrancy-after-istanbul/&gt;[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot&apos;s contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler&apos;s defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.
    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction&apos;s gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;
    uint256 private _status;
    constructor() {
        _status = _NOT_ENTERED;
    }
    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }
    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, &quot;ReentrancyGuard: reentrant call&quot;);
        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }
    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // &lt;https://eips.ethereum.org/EIPS/eip-2200&gt;)
        _status = _NOT_ENTERED;
    }
    /**
     * @dev Returns true if the reentrancy guard is currently set to &quot;entered&quot;, which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-comment">// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)</span>

<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.0;</span>
<span class="hljs-comment">/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * &#x3C;https://blog.openzeppelin.com/reentrancy-after-istanbul/>[Reentrancy After Istanbul].
 */</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">ReentrancyGuard</span> </span>{
    <span class="hljs-comment">// Booleans are more expensive than uint256 or any type that takes up a full</span>
    <span class="hljs-comment">// word because each write operation emits an extra SLOAD to first read the</span>
    <span class="hljs-comment">// slot's contents, replace the bits taken up by the boolean, and then write</span>
    <span class="hljs-comment">// back. This is the compiler's defense against contract upgrades and</span>
    <span class="hljs-comment">// pointer aliasing, and it cannot be disabled.</span>
    <span class="hljs-comment">// The values being non-zero value makes deployment a bit more expensive,</span>
    <span class="hljs-comment">// but in exchange the refund on every call to nonReentrant will be lower in</span>
    <span class="hljs-comment">// amount. Since refunds are capped to a percentage of the total</span>
    <span class="hljs-comment">// transaction's gas, it is best to keep them low in cases like this one, to</span>
    <span class="hljs-comment">// increase the likelihood of the full refund coming into effect.</span>
    <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _NOT_ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">2</span>;
    <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> _status;
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        _status <span class="hljs-operator">=</span> _NOT_ENTERED;
    }
    <span class="hljs-comment">/**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">nonReentrant</span>(<span class="hljs-params"></span>) </span>{
        _nonReentrantBefore();
        <span class="hljs-keyword">_</span>;
        _nonReentrantAfter();
    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_nonReentrantBefore</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">private</span></span> </span>{
        <span class="hljs-comment">// On the first call to nonReentrant, _status will be _NOT_ENTERED</span>
        <span class="hljs-built_in">require</span>(_status <span class="hljs-operator">!</span><span class="hljs-operator">=</span> _ENTERED, <span class="hljs-string">"ReentrancyGuard: reentrant call"</span>);
        <span class="hljs-comment">// Any calls to nonReentrant after this point will fail</span>
        _status <span class="hljs-operator">=</span> _ENTERED;
    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_nonReentrantAfter</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">private</span></span> </span>{
        <span class="hljs-comment">// By storing the original value once again, a refund is triggered (see</span>
        <span class="hljs-comment">// &#x3C;https://eips.ethereum.org/EIPS/eip-2200>)</span>
        _status <span class="hljs-operator">=</span> _NOT_ENTERED;
    }
    <span class="hljs-comment">/**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_reentrancyGuardEntered</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span></span>) </span>{
        <span class="hljs-keyword">return</span> _status <span class="hljs-operator">=</span><span class="hljs-operator">=</span> _ENTERED;
    }
}
</code></pre><p>I am interested in the below section of the code.</p><pre data-type="codeBlock" text="uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
"><code><span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _NOT_ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;
<span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">2</span>;
<span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> _status;
</code></pre><p><strong>Why is OpenZeppelin using <em>1 and 2</em> integer constants and not <em>0 and 1</em> constant integers or <em>false and true</em> boolean constants to mark the entry and exit of execution of the code block?</strong></p><p>The simple answer here is again <code>Gas Optimization</code>.</p><p>The best way to understand this is by</p><ol><li><p>Creating a sample contract and checking the gas utilization of certain functions.</p></li><li><p>Learning about the EVM and opcodes in a certain depth</p></li><li><p>We will also visit certain snippets (The Uncharted Territory by most Solidity Developers) in the yellow paper.</p></li></ol><p>Hence we will do this over multiple articles.</p><h2 id="h-zero-values" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Zero Values</h2><p>The default value of a variable is also called <code>Zero Value</code>. Examples are</p><pre data-type="codeBlock" text="0 --&gt; for intergers and unsigned integers
false --&gt; for booleans
0x0000000000000000000000000000000000000000 --&gt; for address
"><code><span class="hljs-number">0</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">></span> <span class="hljs-keyword">for</span> intergers and unsigned integers
<span class="hljs-literal">false</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">></span> <span class="hljs-keyword">for</span> booleans
<span class="hljs-number">0x0000000000000000000000000000000000000000</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">></span> <span class="hljs-keyword">for</span> <span class="hljs-keyword">address</span>
</code></pre><h2 id="h-non-zero-values" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Non-Zero Values</h2><p>Any value other than zero values are non-zero values for that variable. Examples are</p><pre data-type="codeBlock" text="permitted numbers other than ZERO -&gt; for integers and non-integers
true -&gt; for boolean
other addresses -&gt; for address
"><code>permitted numbers other than ZERO <span class="hljs-operator">-</span><span class="hljs-operator">></span> <span class="hljs-keyword">for</span> integers and non<span class="hljs-operator">-</span>integers
<span class="hljs-literal">true</span> <span class="hljs-operator">-</span><span class="hljs-operator">></span> <span class="hljs-keyword">for</span> boolean
other addresses <span class="hljs-operator">-</span><span class="hljs-operator">></span> <span class="hljs-keyword">for</span> <span class="hljs-keyword">address</span>
</code></pre><p><strong>So what is the importance of this distinction?</strong></p><blockquote><p>Zero Values do not occupy any storage in the blockchain. Irrespective of what storage slot or variable type is associated with a slot, the blockchain does not need to manage the zero values as they are default. At the same time, any non-zero value that is to be stored on the chain needs to be updated on all the nodes of that chain.</p></blockquote><p>Let’s take the below code sample deployed with no optimization</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract Example {
    uint256 val;
    // Input : 100 
    // Transaction Cost: 43702 gas
    // Execution Cost = 43702 - 21000 = ~22500+ gas
    // SSTORE = 20000 units
    // Input : 0 
    // Transaction Cost: 21709 gas
    // Execution Cost = 21709 - 21000 = ~709 gas? 
    // But the actual execution cost is 5398 units
    function setval(uint256 _val) external {
        val = _val;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> 0.8.19;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Example</span> </span>{
    <span class="hljs-keyword">uint256</span> val;
    <span class="hljs-comment">// Input : 100 </span>
    <span class="hljs-comment">// Transaction Cost: 43702 gas</span>
    <span class="hljs-comment">// Execution Cost = 43702 - 21000 = ~22500+ gas</span>
    <span class="hljs-comment">// SSTORE = 20000 units</span>
    <span class="hljs-comment">// Input : 0 </span>
    <span class="hljs-comment">// Transaction Cost: 21709 gas</span>
    <span class="hljs-comment">// Execution Cost = 21709 - 21000 = ~709 gas? </span>
    <span class="hljs-comment">// But the actual execution cost is 5398 units</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setval</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _val</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> </span>{
        val <span class="hljs-operator">=</span> _val;
    }
}
</code></pre><p><code>val</code> is initialized to zero on contract deployment And can be set to a desired unsigned integer using setVal.</p><p>Points to note:</p><ol><li><p>Setting the uint256 val to 100 consumes more than 20000 units of gas towards storing the value on the chain. This is <code>zero to non-zero</code> transition. They are costly.</p></li><li><p>Setting the uint256 val to 0 consumes just 709 units of gas for storing the zero-value on the chain. This is <code>non-zero to zero</code> transition. They are gas-saving because the blockchain does not need to store the data on the chain. Hence Ethereum rewards the removal of value from the chain. Only 709 gas units of the sender are used while the execution cost is 5398 units.</p></li><li><p>A total of 23000+ units of gas for set and unset of <code>val</code>.</p></li></ol><p>Now lets the try the sample with slight changes. <code>val</code> is initialized to 1.</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract Example {
    uint256 val = 1 ;
    // Input : 100 
    // Transaction Cost: 26602 gas
    // Execution Cost = 26602 - 21000 = 5398 gas
    // Input : 1 
    // Transaction Cost: 26602 gas
    // Execution Cost = 26602 - 21000 = 5398 gas
    function setval(uint256 _val) external {
        val = _val;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> 0.8.19;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Example</span> </span>{
    <span class="hljs-keyword">uint256</span> val <span class="hljs-operator">=</span> <span class="hljs-number">1</span> ;
    <span class="hljs-comment">// Input : 100 </span>
    <span class="hljs-comment">// Transaction Cost: 26602 gas</span>
    <span class="hljs-comment">// Execution Cost = 26602 - 21000 = 5398 gas</span>
    <span class="hljs-comment">// Input : 1 </span>
    <span class="hljs-comment">// Transaction Cost: 26602 gas</span>
    <span class="hljs-comment">// Execution Cost = 26602 - 21000 = 5398 gas</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setval</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> _val</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> </span>{
        val <span class="hljs-operator">=</span> _val;
    }
}
</code></pre><p>Points to note:</p><ol><li><p>Setting the uint256 val to 100 consumes 5398 units of gas for storing the value on the chain. This is a <code>non-zero to non-zero</code> transition. And the same for setting <code>val</code> to 1.</p></li><li><p>A total of 10600+ units of gas for set and unset of <code>val</code>.</p></li></ol><blockquote><p>This is why ReentrancyGuard does not use either bool or zero-values for setting and unsettling the variable values in places where the values of a variable toggle frequently.</p><p>Just pick up a token and check its transactions and most likely you will see varying gas units consumed for the same token transfer and this is most likely the reason for the varying gas units consumed.</p></blockquote><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>In conclusion, choose not only the variable type but also the initial variable values carefully.</p><p>Such excellent learning from just one contract of the OpenZeppelin. Kudos to the OZ team.</p>]]></content:encoded>
            <author>anuha@newsletter.paragraph.com (aṇuha)</author>
        </item>
        <item>
            <title><![CDATA[Solidity Audit  Preparation - Footium@ Sherlock]]></title>
            <link>https://paragraph.com/@anuha/solidity-audit-preparation-footium-sherlock</link>
            <guid>IhkS9zJ5FYj1DjMbwPHe</guid>
            <pubDate>Mon, 01 May 2023 07:13:39 GMT</pubDate>
            <description><![CDATA[Footium is a multiplayer football management game where players own and manage a digital football club. To get involved with the Footium universe one needs to own a Footium club. As a Footium club owner, one will receive: 🎮 GAME ACCESS: Gain access to the game 🏟️ STADIUM: A unique, 3D stadium associated with your club ⚜️ BADGE: A generative club badge that can be upgraded 📖 LORE: Unique, AI-generated lore for each club, including info on the fanbase, history, and more that can evolve throu...]]></description>
            <content:encoded><![CDATA[<p>Footium is a multiplayer football management game where players own and manage a digital football club.</p><p>To get involved with the Footium universe one needs to own a Footium club. As a Footium club owner, one will receive:</p><p>🎮 GAME ACCESS: Gain access to the game</p><p>🏟️ STADIUM: A unique, 3D stadium associated with your club</p><p>⚜️ BADGE: A generative club badge that can be <strong>upgraded</strong></p><p>📖 LORE: Unique, AI-generated lore for each club, including info on the fanbase, history, and more that can evolve through in-game achievements</p><p>👕 KIT: Club kit and colors for your team</p><p>👨🏻‍🤝‍👨🏾 SQUAD: An initial squad of 20 players of varying positions and ratings</p><p>🏫 ACADEMY: An academy that produces new youth players every season</p><p>Minted Clubs:</p><p>At the moment clubs are only available on secondary markets.</p><p><strong>Rarible</strong>: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://rarible.com/footium/items">https://rarible.com/footium/items</a></p><p><strong>OpenSea</strong>: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/collection/footium-football-clubs">https://opensea.io/collection/footium-football-clubs</a></p><h2 id="h-assets" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Assets</h2><h2 id="h-club-nfts" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Club NFTs</h2><p>ERC721 Tokens: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/token/0x659cf1306edba213d1fb8f9352b4593a82b05d0c">https://etherscan.io/token/0x659cf1306edba213d1fb8f9352b4593a82b05d0c</a></p><p>The club NFTs have the below attributes:</p><ol><li><p>Place:</p><ul><li><p>Club Colour :</p><ul><li><p>League: Each division has $2^n$ leagues, &lt;String as “Division 8, League 136”&gt;</p></li><li><p>Division : 1- 8</p><ul><li><p>Stadium Capacity:</p></li></ul><pre data-type="codeBlock" text="{
  &quot;name&quot;: &quot;Swafornbursh&quot;,
  &quot;description&quot;: &quot;Swafornbursh F.C. is a professional football club based in Swafornbursh.&quot;,
  &quot;external_url&quot;: &quot;&lt;https://footium.club/ethereum/clubs/624&gt;&quot;,
  &quot;image&quot;: &quot;ipfs://Qmbs8JSa5hFxoktUcqzeVBqLsaKiSfDcdh3FMpi3NMgj5c/624.svg&quot;,
  &quot;attributes&quot;: [
    {
      &quot;trait_type&quot;: &quot;Place&quot;,
      &quot;value&quot;: &quot;Swafornbursh&quot;
    },
    {
      &quot;trait_type&quot;: &quot;Club colours&quot;,
      &quot;value&quot;: &quot;Blue and white&quot;
    },
    {
      &quot;trait_type&quot;: &quot;League&quot;,
      &quot;value&quot;: &quot;Division 8 - League 136&quot;
    },
    {
      &quot;display_type&quot;: &quot;number&quot;,
      &quot;trait_type&quot;: &quot;Division&quot;,
      &quot;value&quot;: 8
    },
    {
      &quot;display_type&quot;: &quot;number&quot;,
      &quot;trait_type&quot;: &quot;Stadium capacity&quot;,
      &quot;value&quot;: 1730
    }
  ]
}
"><code><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">"name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Swafornbursh"</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"description"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Swafornbursh F.C. is a professional football club based in Swafornbursh."</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"external_url"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"&#x3C;https://footium.club/ethereum/clubs/624>"</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"image"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"ipfs://Qmbs8JSa5hFxoktUcqzeVBqLsaKiSfDcdh3FMpi3NMgj5c/624.svg"</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"attributes"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">"trait_type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Place"</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">"value"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Swafornbursh"</span>
    <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">"trait_type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Club colours"</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">"value"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Blue and white"</span>
    <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">"trait_type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"League"</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">"value"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Division 8 - League 136"</span>
    <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">"display_type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"number"</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">"trait_type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Division"</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">"value"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">8</span>
    <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">"display_type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"number"</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">"trait_type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Stadium capacity"</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">"value"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1730</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>More Info: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://footium.gitbook.io/footium-wiki/assets-breakdown/clubs">https://footium.gitbook.io/footium-wiki/assets-breakdown/clubs</a></p><h2 id="h-academy" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Academy</h2><p>The academy is how new talent enters the game. All the players enter the game aged 18.</p><ul><li><p>New football players up to age 20 are part of academy, bound to the club. Can play in the first team. Not on-chain</p></li><li><p>Greater than 20 are free agents that can be minted into the squad else any club can buy at auction.</p></li><li><p>Owning the player NFT, the club can sell or loan players</p></li><li><p>10 new academy prospects every season(about a month in realtime).</p></li><li><p>Within each cohort there will be a varied distribution of quality</p></li><li><p>On chain : NFT player and contract</p></li><li><p>Off chain: Academy prospect</p></li></ul><p><strong>Player Signing</strong></p><p>Club owner wants to sign a youth player on a contract, they mint them as an NFT. This will incur a <strong>small minting fee(in footium tokens)</strong> that will go toward funding prize pools corresponding to the club’s league</p><p><strong>Infrastructure Investments</strong></p><p>Investing in the club’s facilities such as the stadium and academy to improve their quality.</p><ul><li><p>Investing in your academy will increase the average quality of players produced.</p></li><li><p>Investing in your stadium will give you the ability to upgrade its appearance and capacity, and also give your team a larger home advantage during home games.</p></li></ul><p><strong>Coaching and Specialisation</strong></p><p>No specific details</p><h2 id="h-stadium" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Stadium</h2><p>Each Footium club comes with a generative, upgradable 3D stadium — no NFT</p><p>Customizable and Upgradeable.</p><p>Home match advantage</p><p><strong>Customisation and Upgrades</strong></p><p>Club owners will be able</p><ul><li><p>to <strong>invest capital( via tokens?)</strong> to enhance their stadium.</p></li><li><p>Higher division — higher upgradability options. can be earned via in-game rewards</p></li></ul><p><strong>Impact on Performance</strong></p><ul><li><p>The home-ground advantage is a real thing.</p></li><li><p>Big Stadium → Big Crowd → Higher team morale → Higher winning chances</p></li></ul><p><strong>Sponsorship Opportunities</strong></p><p>Big plans ahead to make Clubs profitable/ operatable via sponsorships</p><p>An artist’s impression of the Footium National Stadium, where the Cup Finals will be played.</p><h2 id="h-players" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Players</h2><p>Every player within the game is an NFT with either generative or bespoke artwork. (Could not find the NFT !!)</p><ul><li><p>generative image</p></li><li><p>generated with a number of randomized attributes that ultimately contribute to their overall rating at the time of their minting</p></li><li><p>as well as their potential future overall rating.</p></li></ul><p>Footium sorts player attributes into how directly they affect the match simulation. These are:</p><p><strong>Influencer Attributes (External)</strong>: Attributes that correspond to the different game state characteristics</p><ol><li><p>Injury status: Players can get injured which puts them out of action for a few games. Waiting for their condition to recover may be a wise move!</p></li><li><p>Captain: A team’s captain is instrumental in binding a team together. Within Footium you must pick a captain from your starting eleven. Players have Leadership ratings, and choosing a captain with a high will give your team a boost. Captains serve to improve morale and therefore overall performance.</p></li><li><p>Training: Training influences players’ performance by improving their skills and teamwork.</p></li><li><p>Stadium: A great stadium can influence player performance by improving home-ground advantage. This morale indirectly impacts match performance by influencing players’ in-game performance</p></li></ol><p><strong>Measured Attributes (Indirect):</strong> Attributes that correspond to the player’s response to external events.</p><ol><li><p>Positioning: A player can be fielded in any position. However, that player’s rating in his optimal position isn’t necessarily transferrable to other positions. Instead, players have a different rating for every position. The position a player is in during a match isn’t their defining characteristic generally, but it guides their decision-making and the nature of their performance on the pitch.</p></li><li><p>Mentality</p></li><li><p>Interceptions</p></li><li><p>Decision making</p></li><li><p>Leadership</p></li></ol><p><strong>Conditional Attributes:</strong> Those attributes that indirectly affect match performance by influencing measured attributes. These attributes correspond to changes in the player’s internal and external state and mental and physical states.</p><ol><li><p><strong>Internal StatesMental: Morale:</strong> External StatesPhysical: Condition corresponds to how physically fresh or tired a player is when playing a game. During a game, a player’s condition falls, and playing many games consecutively without rest can lead to significantly worsened performance</p></li><li><p>**ConditionMental: Experience/Familiarity: **Experience is a function of the amount and the quality of a player’s match experience. Players gain experience by playing in matches. This improves the skills of the player, with a bias towards the main skills used in the position they played in for each match. For example, a <strong><em>centre-back</em></strong> will gain a lot of experience in <strong><em>tackling</em></strong>, whilst a <strong><em>center-forward</em></strong> would gain experience <strong><em>shooting</em></strong>.</p></li></ol><p>Math affecting the in-game match simulation <strong>(ELO rating)</strong>: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://footium.gitbook.io/footium-wiki/assets-breakdown/players/conditional-attributes/condition">https://footium.gitbook.io/footium-wiki/assets-breakdown/players/conditional-attributes/condition</a></p><p><strong>Measured Attributes (Direct):</strong> Those attributes that directly affect events in the match</p><ol><li><p>Heading</p></li><li><p>Shooting</p></li><li><p>Pace</p></li><li><p>Dribbling, etc.</p></li></ol><p>More on direct and indirect attributes here: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://footium.gitbook.io/footium-wiki/assets-breakdown/players/measured-attributes">https://footium.gitbook.io/footium-wiki/assets-breakdown/players/measured-attributes</a></p><h2 id="h-competitions" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Competitions</h2><h2 id="h-league-competitions" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">League Competitions</h2><p>Division: 1–8. (More in the future?)</p><p>Each division has $2^{division-1}$ leagues</p><p>Currently, the bottom of the FFL, Division 8, has 128 leagues of 12 teams (1,536 clubs in Division 8)*(from the doc)</p><p><strong>Note: Clubs in Division 1 cannot be promoted and clubs in Division 8 cannot be relegated.(Check on this ?)</strong></p><p>Games take place every day in seasons of 22 games.</p><h2 id="h-cup-competitions" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Cup Competitions</h2><p>Some discrepancies in the doc itself with the number of cup competitions. May not be relevant to solidity though. Will wait for further details</p><h2 id="h-gameplay" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Gameplay</h2><p>I do not expect everything to be on the chain. I guess things like the Tactics, Strategy shall be off-chain.</p><h2 id="h-prize-pools-sources" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Prize Pools Sources</h2><p><strong>Academy Players</strong></p><p>Signing an academy player as part of the squad requires a “signing-on” fee, which is used for prize pools. Once an unsigned player reaches 21 they become a free agent and can be signed by any club. If you release him, any other club will be able to sign him via an auction.</p><ul><li><p><strong>Signing Fee/ minting fee</strong></p></li></ul><p><strong>Transfer Market</strong></p><ul><li><p><strong>Transfer Fees applicable on Payer transfer — 5% → Club’s League prize pool</strong></p></li></ul><p><strong>Loans</strong></p><ul><li><p>Player Loan at a price or free on staking the player asset</p></li></ul><p><strong>Academy Improvements</strong></p><p>Clubs will be able to purchase more coaching slots for your club, corresponding to how many coaches you can employ at any given time. This goes into the prize pool of the purchasing club’s league.</p><p><strong>Stadium Improvements</strong></p><p>You will be able to upgrade your stadium with larger and more stylistic stands by spending Footium tokens. These fees also flow into the prize pool for your league. Functionally, this permits a larger fanbase**,** leading to better morale and performance for your team, and visually allowing you to flex your club’s prestige.</p><p><strong>Legendary Player Auctions</strong></p><p>Each season we will auction off 20 Legendary players. These players will have bespoke artwork designed by different artists in different styles, as well as strong in-game stats and a high potential maximum rating.</p><p>The revenue generated from sales of Legendary players will go into prize pools split across all divisions.</p><p>Potential to have real-world players as Legendary players in the game in future.</p><p><strong>Sponsorship</strong></p><p>Sponsorship of Footium divisions</p><p><strong>Prize Distribution</strong></p><p>Prizes will be split across the Top 9 teams finishing each league season. The payout of the prize pool for each position will follow the distribution in the table below:</p><p>Position % of Prize Pool Payout 1st 28 2nd 20 3rd 16 4th 10 5th 8 6th 6 7th 5 8th 4 9th 3</p><p>Bottom 3 teams to relegate to the lower division. !st team to automatically promote to the higher division.</p><p><strong>Revenue split</strong></p><p>Initially, all revenue generated in-game will go into the prize pools. In the future.</p><h2 id="h-previous-audit-history" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Previous Audit History</h2><p>None: Juicy fresh bugs.</p><h2 id="h-scope" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Scope</h2><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/logiclogue/footium-eth-shareable/tree/6c181ea79af7f6715e3891e65ea5ee8def1e957c">footium-eth-shareable @ 6c181ea79af7f6715e3891e65ea5ee8def1e957c</a></p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumAcademy.sol">footium-eth-shareable/contracts/FootiumAcademy.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumClub.sol">footium-eth-shareable/contracts/FootiumClub.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumClubMinter.sol">footium-eth-shareable/contracts/FootiumClubMinter.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumEscrow.sol">footium-eth-shareable/contracts/FootiumEscrow.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumGeneralPaymentContract.sol">footium-eth-shareable/contracts/FootiumGeneralPaymentContract.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumPlayer.sol">footium-eth-shareable/contracts/FootiumPlayer.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumPrizeDistributor.sol">footium-eth-shareable/contracts/FootiumPrizeDistributor.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/FootiumToken.sol">footium-eth-shareable/contracts/FootiumToken.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/common/Errors.sol">footium-eth-shareable/contracts/common/Errors.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/interfaces/IFootiumClub.sol">footium-eth-shareable/contracts/interfaces/IFootiumClub.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/interfaces/IFootiumPlayer.sol">footium-eth-shareable/contracts/interfaces/IFootiumPlayer.sol</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://app.sherlock.xyz/audits/contests/footium-eth-shareable/contracts/mocks/FootiumPlayerMockV2.sol">footium-eth-shareable/contracts/mocks/FootiumPlayerMockV2.sol</a></p></li></ul><h2 id="h-eips" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">EIPs</h2><p>The FootiumEscrow contract complies with the EIP-1271 (Standard Signature Validation Method for Contracts) standard, the purpose is for each club to have its own FootiumEscrow contract deployed, and each contract can create a signature for OpenSea to buy or sell FootiumPlayer NFTs</p><p><strong>ERC20</strong></p><p><strong>ERC721</strong></p></li></ul></li></ul></li></ol>]]></content:encoded>
            <author>anuha@newsletter.paragraph.com (aṇuha)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/2007510d1125cf132b4024cabfaff5871fd59b15e6b92ee1fec8a1ee3034bbb7.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Solidity Gas Golfing #2]]></title>
            <link>https://paragraph.com/@anuha/solidity-gas-golfing-2</link>
            <guid>sSd04QQ2HuID1NZEtjE7</guid>
            <pubDate>Thu, 06 Apr 2023 13:56:41 GMT</pubDate>
            <description><![CDATA[Gas Golfing #2: Packing VariablesThis article is a continuation of Gas Golfing #1. In the previous article, we discussed how uint8 consumes more gas than uint256. Then a very natural question arises.Variable PackingIf uint8 costs more than uint256 then what is the need to have all of those supported units from 8 256 and why not have uint256 alone? The simple answer to that question is variable packing in solidity. Let us understand more of that through an example. (Deployment optimized for 10...]]></description>
            <content:encoded><![CDATA[<h2 id="h-gas-golfing-2-packing-variables" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Gas Golfing #2: Packing Variables</h2><p>This article is a continuation of <code>Gas Golfing #1</code>. In the previous article, we discussed how <code>uint8</code> consumes more gas than <code>uint256</code>. Then a very natural question arises.</p><h2 id="h-variable-packing" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Variable Packing</h2><p><strong>If uint8 costs more than uint256 then what is the need to have all of those supported units from 8 256 and why not have uint256 alone?</strong></p><p>The simple answer to that question is variable packing in solidity. Let us understand more of that through an example. (Deployment optimized for 1000 runs)</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract VariablePacking {
    uint8 smallNum = 21;  // Occupies Slot 0 of Storage
    uint8 anotherSmallNum = 22; // Occupies Slot 0 of Storage
    uint256 bigNum = 12134567890; // Occupies Slot 1 of Storage
    // 2351 gas (Cost only applies when called by a contract)
    function readSmallNum() public view returns(uint8){
        return smallNum;
    }
    // 2307gas (Cost only applies when called by a contract)
    function readAnotherSmallNum() public view returns(uint8){
        return anotherSmallNum;
    }
    // 2248 gas (Cost only applies when called by a contract)
    function readBigNum() public view returns(uint256){
        return bigNum;
    }
    // Input 0: 0x0000000000000000000000000000000000000000000000000000000000001615
    // Input 1: 0x00000000000000000000000000000000000000000000000000000002d346cfd2
    function getValueAtSlot(uint256 slotNum) public view returns (bytes32) {
        bytes32 value;
        assembly {
            value := sload(slotNum)
        }
        return value;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.19;</span>
<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">VariablePacking</span> </span>{
    <span class="hljs-keyword">uint8</span> smallNum <span class="hljs-operator">=</span> <span class="hljs-number">21</span>;  <span class="hljs-comment">// Occupies Slot 0 of Storage</span>
    <span class="hljs-keyword">uint8</span> anotherSmallNum <span class="hljs-operator">=</span> <span class="hljs-number">22</span>; <span class="hljs-comment">// Occupies Slot 0 of Storage</span>
    <span class="hljs-keyword">uint256</span> bigNum <span class="hljs-operator">=</span> <span class="hljs-number">12134567890</span>; <span class="hljs-comment">// Occupies Slot 1 of Storage</span>
    <span class="hljs-comment">// 2351 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readSmallNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint8</span></span>)</span>{
        <span class="hljs-keyword">return</span> smallNum;
    }
    <span class="hljs-comment">// 2307gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readAnotherSmallNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint8</span></span>)</span>{
        <span class="hljs-keyword">return</span> anotherSmallNum;
    }
    <span class="hljs-comment">// 2248 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readBigNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>{
        <span class="hljs-keyword">return</span> bigNum;
    }
    <span class="hljs-comment">// Input 0: 0x0000000000000000000000000000000000000000000000000000000000001615</span>
    <span class="hljs-comment">// Input 1: 0x00000000000000000000000000000000000000000000000000000002d346cfd2</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getValueAtSlot</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> slotNum</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes32</span></span>) </span>{
        <span class="hljs-keyword">bytes32</span> value;
        <span class="hljs-keyword">assembly</span> {
            value <span class="hljs-operator">:=</span> <span class="hljs-built_in">sload</span>(slotNum)
        }
        <span class="hljs-keyword">return</span> value;
    }
}
</code></pre><p>This sample just adds another variable <code>anotherSmallNum</code> to the previous example and a getter function for the same. This slightly changes the gas units consumed.</p><blockquote><p>📑 But an important thing to note is that the values <code>smallNum</code> and <code>anotherSmallNum</code> occupy the slot0 of the storage. So there is less initial gas cost on deployment. But higher execution gas consumption. The solidity compiler does this by <strong>packing of variables</strong> in a slot whenever applicable.</p></blockquote><p>A refactor in the below way can be beneficial concerning gas consumed in execution. But at the cost of using an extra storage slot during deployment.</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract Refactored {
    uint256 smallNum = 21;  // Occupies Slot 0 of Storage
    uint256 anotherSmallNumber = 22; // Occupies Slot 0 of Storage
    uint256 bigNum = 12134567890; // Occupies Slot 1 of Storage
    // 2324 gas (Cost only applies when called by a contract)
    function readSmallNum() public view returns(uint256){
        return smallNum;
    }
    // 2280gas (Cost only applies when called by a contract)
    function readAnotherSmallNum() public view returns(uint256){
        return anotherSmallNumber;
    }
    // 2247 gas (Cost only applies when called by a contract)
    function readBigNum() public view returns(uint256){
        return bigNum;
    }
    // Input 0: 0x0000000000000000000000000000000000000000000000000000000000000015
  // Input 1: 0x0000000000000000000000000000000000000000000000000000000000000016
    // Input 2: 0x00000000000000000000000000000000000000000000000000000002d346cfd2
    function getValueAtSlot(uint256 slotNum) public view returns (bytes32) {
        bytes32 value;
        assembly {
            value := sload(slotNum)
        }
        return value;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.19;</span>
<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Refactored</span> </span>{
    <span class="hljs-keyword">uint256</span> smallNum <span class="hljs-operator">=</span> <span class="hljs-number">21</span>;  <span class="hljs-comment">// Occupies Slot 0 of Storage</span>
    <span class="hljs-keyword">uint256</span> anotherSmallNumber <span class="hljs-operator">=</span> <span class="hljs-number">22</span>; <span class="hljs-comment">// Occupies Slot 0 of Storage</span>
    <span class="hljs-keyword">uint256</span> bigNum <span class="hljs-operator">=</span> <span class="hljs-number">12134567890</span>; <span class="hljs-comment">// Occupies Slot 1 of Storage</span>
    <span class="hljs-comment">// 2324 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readSmallNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>{
        <span class="hljs-keyword">return</span> smallNum;
    }
    <span class="hljs-comment">// 2280gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readAnotherSmallNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>{
        <span class="hljs-keyword">return</span> anotherSmallNumber;
    }
    <span class="hljs-comment">// 2247 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readBigNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>{
        <span class="hljs-keyword">return</span> bigNum;
    }
    <span class="hljs-comment">// Input 0: 0x0000000000000000000000000000000000000000000000000000000000000015</span>
  <span class="hljs-comment">// Input 1: 0x0000000000000000000000000000000000000000000000000000000000000016</span>
    <span class="hljs-comment">// Input 2: 0x00000000000000000000000000000000000000000000000000000002d346cfd2</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getValueAtSlot</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> slotNum</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes32</span></span>) </span>{
        <span class="hljs-keyword">bytes32</span> value;
        <span class="hljs-keyword">assembly</span> {
            value <span class="hljs-operator">:=</span> <span class="hljs-built_in">sload</span>(slotNum)
        }
        <span class="hljs-keyword">return</span> value;
    }
}
</code></pre><h2 id="h-when-to-use-variable-packing" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">When to use variable packing?</h2><p><strong>So is the</strong> <code>packing of variables</code> of any use at all?</p><p>It is useful when all the variables in the slot are read together. Like via the structs.</p><p>Let’s look at the sample codes below and check their gas utilization. (Deployment optimized for 1000 runs)</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract PackingInStructs {
    struct VariablesNotPacked{
        address myAddress;
        uint256 myage;
        bool areYouHappy;
    }
    struct VariablesPacked{
        bool areYouHappy;
        uint8 myage;
        address myAddress;
    }
    VariablesNotPacked a;
    VariablesPacked b;
    constructor() {
        a = VariablesNotPacked(msg.sender, 36, false);
        b = VariablesPacked(true, 36, msg.sender); 
    }
    // 6774 gas (Cost only applies when called by a contract)
    function readVariablesNotPacked() public view returns(VariablesNotPacked memory){
        return a;
    }
    // 2550 gas (Cost only applies when called by a contract)
    function readVariablesPacked() public view returns(VariablesPacked memory){
        return b;
    }
    // Input 0: 0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4  - a.myAddress
    // Input 1: 0x0000000000000000000000000000000000000000000000000000000000000024  - a.age
    // Input 2: 0x0000000000000000000000000000000000000000000000000000000000000000  - a.areYouHappy
    // Input 3: 0x00000000000000000000|5b38da6a701c568545dcfcb03fcb875f56beddc4|24|01|
    //            - | b.myAddress | b.age | b.areYouHappy|
    function getValueAtSlot(uint256 slotNum) public view returns (bytes32) {
        bytes32 value;
        assembly {
            value := sload(slotNum)
        }
        return value;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.19;</span>
<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">PackingInStructs</span> </span>{
    <span class="hljs-keyword">struct</span> <span class="hljs-title">VariablesNotPacked</span>{
        <span class="hljs-keyword">address</span> myAddress;
        <span class="hljs-keyword">uint256</span> myage;
        <span class="hljs-keyword">bool</span> areYouHappy;
    }
    <span class="hljs-keyword">struct</span> <span class="hljs-title">VariablesPacked</span>{
        <span class="hljs-keyword">bool</span> areYouHappy;
        <span class="hljs-keyword">uint8</span> myage;
        <span class="hljs-keyword">address</span> myAddress;
    }
    VariablesNotPacked a;
    VariablesPacked b;
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        a <span class="hljs-operator">=</span> VariablesNotPacked(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-number">36</span>, <span class="hljs-literal">false</span>);
        b <span class="hljs-operator">=</span> VariablesPacked(<span class="hljs-literal">true</span>, <span class="hljs-number">36</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>); 
    }
    <span class="hljs-comment">// 6774 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readVariablesNotPacked</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params">VariablesNotPacked <span class="hljs-keyword">memory</span></span>)</span>{
        <span class="hljs-keyword">return</span> a;
    }
    <span class="hljs-comment">// 2550 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readVariablesPacked</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params">VariablesPacked <span class="hljs-keyword">memory</span></span>)</span>{
        <span class="hljs-keyword">return</span> b;
    }
    <span class="hljs-comment">// Input 0: 0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4  - a.myAddress</span>
    <span class="hljs-comment">// Input 1: 0x0000000000000000000000000000000000000000000000000000000000000024  - a.age</span>
    <span class="hljs-comment">// Input 2: 0x0000000000000000000000000000000000000000000000000000000000000000  - a.areYouHappy</span>
    <span class="hljs-comment">// Input 3: 0x00000000000000000000|5b38da6a701c568545dcfcb03fcb875f56beddc4|24|01|</span>
    <span class="hljs-comment">//            - | b.myAddress | b.age | b.areYouHappy|</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getValueAtSlot</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> slotNum</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes32</span></span>) </span>{
        <span class="hljs-keyword">bytes32</span> value;
        <span class="hljs-keyword">assembly</span> {
            value <span class="hljs-operator">:=</span> <span class="hljs-built_in">sload</span>(slotNum)
        }
        <span class="hljs-keyword">return</span> value;
    }
}
</code></pre><blockquote><p>📑 Below is the summary</p><p>Note the huge difference in gas units consumed</p><p>Note how the storage slot for <code>VariablesNotPacked</code> is spread across 3 slots while only one slot in <code>VariabledPacked</code></p></blockquote><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>In conclusion, choosing the appropriate data type is essential when designing smart contracts in Solidity. Also, enable variable packing by crafty arrangements of the variables.</p><p>Links:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/sudeepjc/anuha/tree/main/contracts/gas-golfing-2">https://github.com/sudeepjc/anuha/tree/main/contracts/gas-golfing-2</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/sudeepjc/anuha/tree/main/test/gas-golfing-2">https://github.com/sudeepjc/anuha/tree/main/test/gas-golfing-2</a></p>]]></content:encoded>
            <author>anuha@newsletter.paragraph.com (aṇuha)</author>
        </item>
        <item>
            <title><![CDATA[Solidity Gas Golfing #1]]></title>
            <link>https://paragraph.com/@anuha/solidity-gas-golfing-1</link>
            <guid>SKcc6r0NihFwJCN1Jgpu</guid>
            <pubDate>Tue, 21 Mar 2023 07:01:23 GMT</pubDate>
            <description><![CDATA[Gas Golfing #1: uint8 vs uint256Below is the ReentrancyGuard.sol from OpenZeppelin// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that beca...]]></description>
            <content:encoded><![CDATA[<h2 id="h-gas-golfing-1-uint8-vs-uint256" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Gas Golfing #1: uint8 vs uint256</h2><p>Below is the ReentrancyGuard.sol from OpenZeppelin</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * &lt;https://blog.openzeppelin.com/reentrancy-after-istanbul/&gt;[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot&apos;s contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler&apos;s defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.
    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction&apos;s gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;
    uint256 private _status;
    constructor() {
        _status = _NOT_ENTERED;
    }
    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }
    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, &quot;ReentrancyGuard: reentrant call&quot;);
        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }
    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // &lt;https://eips.ethereum.org/EIPS/eip-2200&gt;)
        _status = _NOT_ENTERED;
    }
    /**
     * @dev Returns true if the reentrancy guard is currently set to &quot;entered&quot;, which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-comment">// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.0;</span>
<span class="hljs-comment">/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * &#x3C;https://blog.openzeppelin.com/reentrancy-after-istanbul/>[Reentrancy After Istanbul].
 */</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">ReentrancyGuard</span> </span>{
    <span class="hljs-comment">// Booleans are more expensive than uint256 or any type that takes up a full</span>
    <span class="hljs-comment">// word because each write operation emits an extra SLOAD to first read the</span>
    <span class="hljs-comment">// slot's contents, replace the bits taken up by the boolean, and then write</span>
    <span class="hljs-comment">// back. This is the compiler's defense against contract upgrades and</span>
    <span class="hljs-comment">// pointer aliasing, and it cannot be disabled.</span>
    <span class="hljs-comment">// The values being non-zero value makes deployment a bit more expensive,</span>
    <span class="hljs-comment">// but in exchange the refund on every call to nonReentrant will be lower in</span>
    <span class="hljs-comment">// amount. Since refunds are capped to a percentage of the total</span>
    <span class="hljs-comment">// transaction's gas, it is best to keep them low in cases like this one, to</span>
    <span class="hljs-comment">// increase the likelihood of the full refund coming into effect.</span>
    <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _NOT_ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">2</span>;
    <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> _status;
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        _status <span class="hljs-operator">=</span> _NOT_ENTERED;
    }
    <span class="hljs-comment">/**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">nonReentrant</span>(<span class="hljs-params"></span>) </span>{
        _nonReentrantBefore();
        <span class="hljs-keyword">_</span>;
        _nonReentrantAfter();
    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_nonReentrantBefore</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">private</span></span> </span>{
        <span class="hljs-comment">// On the first call to nonReentrant, _status will be _NOT_ENTERED</span>
        <span class="hljs-built_in">require</span>(_status <span class="hljs-operator">!</span><span class="hljs-operator">=</span> _ENTERED, <span class="hljs-string">"ReentrancyGuard: reentrant call"</span>);
        <span class="hljs-comment">// Any calls to nonReentrant after this point will fail</span>
        _status <span class="hljs-operator">=</span> _ENTERED;
    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_nonReentrantAfter</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">private</span></span> </span>{
        <span class="hljs-comment">// By storing the original value once again, a refund is triggered (see</span>
        <span class="hljs-comment">// &#x3C;https://eips.ethereum.org/EIPS/eip-2200>)</span>
        _status <span class="hljs-operator">=</span> _NOT_ENTERED;
    }
    <span class="hljs-comment">/**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_reentrancyGuardEntered</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span></span>) </span>{
        <span class="hljs-keyword">return</span> _status <span class="hljs-operator">=</span><span class="hljs-operator">=</span> _ENTERED;
    }
}
</code></pre><p>I am interested in the below section of the code.</p><pre data-type="codeBlock" text="uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
"><code><span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _NOT_ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;
<span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">constant</span> _ENTERED <span class="hljs-operator">=</span> <span class="hljs-number">2</span>;
<span class="hljs-keyword">uint256</span> <span class="hljs-keyword">private</span> _status;
</code></pre><p><strong>Why is OpenZeppelin using</strong> <code>uint256</code> as against <code>uint8</code> when the only required values <code>1</code> and <code>2</code> can fit in the range of <code>uint8</code>?</p><p>The simple answer is <code>Gas Optimization</code>.</p><p>When writing smart contracts in Solidity, gas optimization is crucial. One way to optimize gas usage is by choosing the appropriate data types. Solidity supported a wide range of unsigned integers ranging between uint8 to uint256 with a gap of 8 bits. In this write-up, we will explore which of these data types is more efficient to store and use.</p><h2 id="h-storage" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Storage</h2><h2 id="h-uint8" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">uint8</h2><p>As the name suggests, uint8 is an unsigned integer that can hold a maximum value of 2⁸-1, which is 255. Therefore, uint8 should use only 1 byte of storage space.</p><h2 id="h-uint256" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">uint256</h2><p>On the other hand, uint256 is an unsigned integer that can hold a maximum value of 2²⁵⁶-1, which is an incredibly large number. Therefore, uint256 requires 32 bytes of storage space.</p><p>Let’s take the below code sample</p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract Example {

    uint8 smallNum = 21;  // Occupies Slot 0 of Storage
    uint256 bigNum = 12134567890; // Occupies Slot 1 of Storage

    // 2311 gas (Cost only applies when called by a contract)
    function readSmallNum() public view returns(uint8){
        return smallNum;
    }

    // 2248 gas (Cost only applies when called by a contract)
    function readBigNum() public view returns(uint256){
        return bigNum;
    }

    // Input 0: 0x0000000000000000000000000000000000000000000000000000000000000015
    // Input 1: 0x00000000000000000000000000000000000000000000000000000002d346cfd2
    function getValueAtSlot(uint256 slotNum) public view returns (bytes32) {
        bytes32 value;
        assembly {
            value := sload(slotNum)
        }
        return value;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.19;</span>
<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Example</span> </span>{

    <span class="hljs-keyword">uint8</span> smallNum <span class="hljs-operator">=</span> <span class="hljs-number">21</span>;  <span class="hljs-comment">// Occupies Slot 0 of Storage</span>
    <span class="hljs-keyword">uint256</span> bigNum <span class="hljs-operator">=</span> <span class="hljs-number">12134567890</span>; <span class="hljs-comment">// Occupies Slot 1 of Storage</span>

    <span class="hljs-comment">// 2311 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readSmallNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint8</span></span>)</span>{
        <span class="hljs-keyword">return</span> smallNum;
    }

    <span class="hljs-comment">// 2248 gas (Cost only applies when called by a contract)</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readBigNum</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)</span>{
        <span class="hljs-keyword">return</span> bigNum;
    }

    <span class="hljs-comment">// Input 0: 0x0000000000000000000000000000000000000000000000000000000000000015</span>
    <span class="hljs-comment">// Input 1: 0x00000000000000000000000000000000000000000000000000000002d346cfd2</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getValueAtSlot</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> slotNum</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes32</span></span>) </span>{
        <span class="hljs-keyword">bytes32</span> value;
        <span class="hljs-keyword">assembly</span> {
            value <span class="hljs-operator">:=</span> <span class="hljs-built_in">sload</span>(slotNum)
        }
        <span class="hljs-keyword">return</span> value;
    }
}
</code></pre><p>In the contract storage, the variables are organized in slots of 32 bytes each irrespective of whether it was uint8 or uint256.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ae08add88121bcf65582feca967c0c86065e245bf8ba077120fa5b0a89a6940a.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Values at a given slot can be accessed by using the assembly code below:</p><pre data-type="codeBlock" text="assembly {
     value := sload(slotNum)
}
"><code><span class="hljs-keyword">assembly</span> {
     value <span class="hljs-operator">:=</span> <span class="hljs-built_in">sload</span>(slotNum)
}
</code></pre><h2 id="h-execution" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Execution</h2><p>The above contract was deployed with optimization turned on for 1000 runs.</p><ul><li><p><code>readBigNum</code> requires <code>2248</code> units of gas</p></li><li><p><code>readSmallNum</code> requires <code>2311</code> units of gas</p></li></ul><blockquote><p>One of the primary reasons why reading the <code>uint8</code> value is costlier than <code>uint256</code> is because when the <code>uint8</code> value is read by EVM it reads the whole slot first and performs extra masking operations, while the uint256 value is returned directly. And any extra opcode operations mean extra gas consumption.</p></blockquote><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>In conclusion, choosing the appropriate data type is essential when designing smart contracts in Solidity. Please consider the learnings from the above section to choose the appropriate data type.</p><p>Now that we know the reason for openzeppelin’’s use of <code>uint256</code> datatypes check the **<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/sudeepjc/anuha"><em>anuha</em>**</a> GitHub repo and gas-golf-1 folder sample that compare and illustrate the ReentrancyGuard.sol‘s uint8 vs uint256 versions.</p><p>Links:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/sudeepjc/anuha/tree/main/contracts/gas-golfing-1">https://github.com/sudeepjc/anuha/tree/main/contracts/gas-golfing-1</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/sudeepjc/anuha/tree/main/test/gas-golfing-1">https://github.com/sudeepjc/anuha/tree/main/test/gas-golfing-1</a></p>]]></content:encoded>
            <author>anuha@newsletter.paragraph.com (aṇuha)</author>
        </item>
        <item>
            <title><![CDATA[aṇuha]]></title>
            <link>https://paragraph.com/@anuha/an-uha</link>
            <guid>cinuXtE7Wh7g6nwssVaq</guid>
            <pubDate>Tue, 21 Mar 2023 06:49:17 GMT</pubDate>
            <description><![CDATA[anuha is a series of articles delving into the details of the advanced concepts of solidity smart contract development. aṇuha is a Sanskrit word that means ‘he who reaches (=knows) the atoms (= the minute details)’. This is my journey of upskilling on the advanced concepts of Solidity Smart Contract Development, Gas optimization, Yul (/huff), Zero-knowledge proofs, EVM, tools, puzzles, fuzzing, and of course auditing.Who am I?Solidity Smart Contract developer || Gas Golfing || Audit || Seaso...]]></description>
            <content:encoded><![CDATA[<p><code>anuha</code> is a series of articles delving into the details of the advanced concepts of solidity smart contract development. <strong><em>aṇuha</em></strong> is a Sanskrit word that means <em>‘he who reaches (=knows) the atoms (= the minute details)’</em>. This is my journey of upskilling on the advanced concepts of <em>Solidity Smart Contract Development, Gas optimization, Yul (/huff), Zero-knowledge proofs, EVM, tools, puzzles, fuzzing,</em> and of course <em>auditing.</em></p><h3 id="h-who-am-i" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Who am I?</h3><p>Solidity Smart Contract developer || Gas Golfing || Audit || Seasoned Software Developer</p><p><strong>Social handles</strong></p><p><em>LinkedIn</em>: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.linkedin.com/in/sudeep-sagar/">https://www.linkedin.com/in/sudeep-sagar/</a></p><p><em>GitHub</em>: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.github.com/sudeepjc">https://www.github.com/sudeepjc</a> (needs serious cleanup)</p><p><em>Twitter: </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.twitter.com/sudeepjc"><em>https://www.twitter.com/sudeepjc</em></a></p>]]></content:encoded>
            <author>anuha@newsletter.paragraph.com (aṇuha)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/b034e9fc84df82cc872918d5f317c732b45c01594b605849c66033d1c885fe18.png" length="0" type="image/png"/>
        </item>
    </channel>
</rss>